Updating deep ReactJS state
-
20-12-2019 - |
Question
I have an array of items in a ReactJS component state that I'm iterating over to create a form. My question is: How do I best update those items when the fields change?
For example:
var items = this.state.foo.bar.items.map(function(item, i) {
return <input value={item.baz} onChange={??}
});
What would my onChange handler look like in this case? Do I change the item.baz
property directly, then this.setState(state)
? Seems wrong. I'm looking at the React immutability helpers, but see how to work with array indexes.
Thanks.
Solution
You could use the index to update the correct array item by passing it to onChange
via bind
and then dynamically building the object to pass to update
:
var Hello = React.createClass({
getInitialState : function() {
return {
foo : {
bar : {
items : [ { baz : 1 }, { baz : 2 }, { baz : 3 } ]
}
}
};
},
onChange : function( idx, item, event ) {
var objForUpdate = { foo: { bar: { items : {} } } };
objForUpdate.foo.bar.items[ idx ] = { $set : { baz : event.target.value } };
var newData = React.addons.update( this.state, objForUpdate );
this.setState( newData );
},
render: function() {
var _this = this;
var items = this.state.foo.bar.items.map(function(item, i) {
return <input value={item.baz} onChange={_this.onChange.bind( _this, i, item )}></input>
});
return <div>{items}</div>;
}
});
My understanding that this only has an advantage over something like
onChange : function( idx, item, event ) {
item.baz = event.target.value;
this.setState( this.state );
}
if you are going to override shouldComponentUpdate
and be more selective about when to rerender than every time this.setState()
is called.
OTHER TIPS
Thought I'd just throw this library out there because it was specifically designed for deeply nested react state,
https://github.com/mquan/cortex
You can update items within each component and it automatically trickles up without you having to define callbacks to pass the event up.