D-Nis
D-Nis

Reputation: 49

How to set value for the checkbox in ReactJS

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

Upvotes: 1

Views: 250

Answers (4)

Drew Reese
Drew Reese

Reputation: 202605

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),
      };
    }
  });
},

Upvotes: 2

Sinan Yaman
Sinan Yaman

Reputation: 5937

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]}
          ))
        }
       }

Upvotes: 0

Saugat
Saugat

Reputation: 21

I think you should use checked property instead of value.

For reference check react js docs here

Upvotes: 0

Erfan
Erfan

Reputation: 1802

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

Upvotes: 0

Related Questions