fprs fprs - 4 months ago 39
Javascript Question

ReactJS: Array of states - uncontrolled input

I'm building component with multiple checkboxes - each for a category.

When I have only one checkbox in boolean var, it works perfectly(similar like in Thinking in React), but when I put states in an array, I'm getting the uncontrolled form warning:


react.js:20541 Warning: CheckComponent is changing a controlled input of >type checkbox to be uncontrolled. Input elements should not switch from >controlled to uncontrolled (or vice versa). Decide between using a >controlled or uncontrolled input element for the lifetime of the >component.


Component:

handleChange: function(e) {
this.props.onUserInput(
this.refs[e.target.name].checked
);
},
render: function(){
var self = this;
return(
<div>
<ul>
{
categories.map(function(d, i){
return (
<li key = {d}>
<input type="checkbox" checked={self.props.checkedBox[i]} name={d} ref={d} onChange={self.handleChange}/>
<span> {d} </span>
</li>
);
})
}
</ul>
</div>
);
}


Parent component:

getInitialState: function(){
return{
checkedBox: [true,true,true,true,true,true,true,true,true,true]
};
},
handleUserInput: function(checkedBox) {
this.setState({
checkedBox: checkedBox
});
},
render: function(){
return(
<div>
<CheckComponent checkedBox={this.state.checkedBox} onUserInput={this.handleUserInput} categories={this.props.categories}/>
<DisplayComponent checkedBox={this.state.checkedBox} data={this.props.data}/>
</div>
);
}


Is something wrong with this array?

Answer

You are replacing array in your state with single value. Just pass checkbox index to onChange function.

handleChange: function(i) {
    this.props.onUserInput(i);
},

...

<input type="checkbox" checked={self.props.checkedBox[i]} name={d} ref={d} onChange={function() {self.handleChange(i);}}/>

Then in your user input just change value at specified index.

handleUserInput: function(i) {
    this.setState({
        checkedBox: this.state.checkedBox.map(function(val, idx) {
                        if (idx === i) return !val; 
                        return val;
                    );
    });
},