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.

Was it helpful?

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.

jsfiddle

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top