In the code below, I have a list of Item
s. Each one renders a component which has an input field to change that items name.
The Item's state is handled all through props, so the parent object is telling the Item what it is, and handling the editing/removal of items (The more complicated version of this uses Redux, and this seems to be the proper way to handle state..)
However, if I set the input field to defaultValue
, then attempt to remove an item, React removes the last item. The state of items, however, shows the correct item having been removed.
Before clicking button:
App state: {items: ['1', '2', '3', '4']}
After:
App state: {items: ['1', '3', '4']}
Again: The 2nd item was removed (as evidence of the html below the button), but react rendered the 4th item removed instead!
source:
import React from 'react';
import ReactDOM from 'react-dom';
var App = React.createClass({
getInitialState: function() {
return { items: ['1', '2', '3', '4'] };
},
removeSecond: function(e) {
e.preventDefault();
this.removeItem(1);
},
editItem: function(index, newItem) {
var newItems = this.state.items.slice();
newItems[index] = newItem;
this.setState({items: newItems});
},
removeItem: function(index) {
var newItems = this.state.items;
newItems.splice(index, 1);
this.setState({items: newItems});
},
render: function() {
var self = this;
return (
<div id='itemsList'>
{ this.state.items.map( function(item, i) {
return <Item name={item}
index={i}
key={i}
editItem={self.editItem}
removeItem={self.removeItem} />;
})}
<form onSubmit={this.removeSecond}>
<button>Remove 2nd</button>
</form>
<div>{this.state.items.map(function(item, i) {
return <p key={i}>{i} : '{item}'</p>;
})}</div>
</div>
);
}
});
var Item = React.createClass({
handleChangeName: function(e) {
this.props.editItem(this.props.index, e.target.value);
},
render: function() {
return (
<div id="item">
<input type="text" defaultValue={this.props.name} onChange={this.handleChangeName} />
</div>);
}
});
ReactDOM.render(
<App />,
document.getElementById('items_test')
);
source code: https://bitbucket.org/MintyAnt/multi_react_items
How do I fix this? Or, what is the proper way to handle state here?