1

I try to show my value using checkbox. Value always comes for the console log. But it didn't set for the checkbox. Here is the code and image for my problem:

     var NotePage = createClass({
 

      addTags(e) {
        console.log("id****************", e.target.id);
        let id = e.target.id;
        let selectedTags = this.state.selectedTags;
        if (selectedTags.includes(id)) {
          var index = selectedTags.indexOf(id)
          selectedTags.splice(index, 1);
        } else {
          selectedTags.push(id);
        }
        console.log("id****************selectedTags", selectedTags);

        this.setState({
          selectedTags: selectedTags
        })

       },







     render: function () {
       assignStates: function (note, token, tagCategories) {
   
           let fields = [];
           fields["title"] = note.title_en;
           fields["body"] = note.body_en;
           let selectedFileName = null
   
           if (note.file_url_en != "") {
             console.log("note.file_url_en ", note.file_url_en);
             selectedFileName = note.file_url_en
   
           }
           let selectedTags = [];
           let n = 0;
           (note.note_tag).forEach(tag => {
             selectedTags.push(tag.id.toString());
             n++;
           });
   
           console.log("id****************first", selectedTags);
   
           let initial_values = {
             note: note,
             id: note.id,
             api: new Api(token),
             message: "",
             title: note.title_en,
             body: note.body_en,
             fields: fields,
             isEdit: false,
             selectedTags: selectedTags,
             tagCategories: tagCategories,
             selectedFileName: selectedFileName,
           }
           return initial_values;
       },
   
       const { selectedTags } = this.state;
             {(tagCategory.tags).map((tag) => (
                           <div className="col-3">
                             <div>
                               <input
                                 type="checkbox"
                                 value={selectedTags.includes(tag.id)}
                                 id={tag.id}
                                 onChange={this.addTags} />
                               <label style={{ marginLeft: "10px", fontSize: "15px" }}>
                                 {tag.name_en}
                               </label>
                             </div>
                           </div>
              ))
      }
   })

Image related for the problem

3
  • Where is your addTags function? Commented Aug 23, 2021 at 6:06
  • Sorry I will added it. Commented Aug 23, 2021 at 6:10
  • @Sinan Yaman can you please check it now Commented Aug 23, 2021 at 6:20

4 Answers 4

2

You've an issue with state mutation. You save a reference to the current state, mutate it, and then save it back into state. This breaks React's use of shallow reference equality checks during reconciliation to determine what needs to be flushed to the DOM.

addTags(e) {
  let id = e.target.id;

  let selectedTags = this.state.selectedTags; // reference to state

  if (selectedTags.includes(id)) {
    var index = selectedTags.indexOf(id)
    selectedTags.splice(index, 1); // mutation!!
  } else {
    selectedTags.push(id); // mutation!!
  }

  this.setState({
    selectedTags: selectedTags // same reference as previous state
  });
},

To remedy you necessarily return a new array object reference.

addTags(e) {
  const { id } = e.target;

  this.setState(prevState => {
    if (prevState.selectedTags.includes(id)) {
      return {
        selectedTags: prevState.selectedTags.filter(el => el !== id),
      };
    } else {
      return {
        selectedTags: prevState.selectedTags.concat(id),
      };
    }
  });
},
Sign up to request clarification or add additional context in comments.

Comments

0

Use the "checked" attribute.

                         <input
                          type="checkbox"

                          value={tag.id}
                          checked={selectedTags.includes(tag.id)}
                          id={tag.id}

                          onChange={this.addTags} />

also, about the value attribute in checkboxes:

A DOMString representing the value of the checkbox. This is not displayed on the client-side, but on the server this is the value given to the data submitted with the checkbox's name.

Note: If a checkbox is unchecked when its form is submitted, there is no value submitted to the server to represent its unchecked state (e.g. value=unchecked); the value is not submitted to the server at all. If you wanted to submit a default value for the checkbox when it is unchecked, you could include an inside the form with the same name and value, generated by JavaScript perhaps.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#value

Comments

0

I think you should use checked property instead of value.

For reference check react js docs here

Comments

0

You are mutating state variable directly with selectedTags.splice(index, 1); and selectedTags.push(id);

What you need to do is make a copy of the state variable and change that:

      addTags(e) {
        let id = e.target.id;
        if (this.state.selectedTags.includes(id)) {
          this.setState(state => (
            {...state, selectedTags: state.selectedTags.filter(tag => tag !== id)}
          ))
        } else {
          this.setState(state => (
            {...state, selectedTags: [...state.selectedTags, id]}
          ))
        }
       }

5 Comments

This is your code, you can replace your addTags function with this. Or, if you can create a codesandbox example, I will make it work. Either this or @DrewReese 's solution should work. Do you get an error?
no errors coming but the checkbox still not ticking
You also need to use checked = {selectedTags.includes(tag.id)} instead of value, as others mentioned.
yes I used with that part but it did't work
Then problem should be somewhere else, can you create a codesandbox?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.