Reputation: 957
I'm learning react and was wondering what's the best way to pass a value from children to parent? Here are my components.
TodoItems -> should pass the value of the button to parent so I can remove the item from state.
var TodoItems = createClass ({
render:function(){
var listItem = this.props.items.map((item) =>{
return <li key={item.key}> {item.text} <button onClick={this.props.removeItem} value={item.key}> x </button></li>
});
return <ul>
{listItem}
</ul>
}
});
This is my Body
component
var Body = createClass ({
displayName: 'Body',
getInitialState:function(){
return {
items: [
{
text:"Buy Fish",
key: "1"
},
{
text:"Learn React",
key: "2"
},{
text:"Buy new shoes",
key:"3"
}]
}
},
addItem(e){
e.preventDefault();
var item = this.refs.taskItem;
var taskItem = this.state.items;
taskItem.push({text:item.value, key:Date.now()});
this.setState(taskItem);
},
removeItem:function(e){
console.log(1);
},
render:function(){
return <div className="body">
<form onSubmit={this.addItem}>
<input ref="taskItem" />
<button type="submit"> Add Item </button>
</form>
<TodoItems removeItem={this.removeItem} {...this.props} items = {this.state.items} />
</div>
}
});
Now Body
should get the key value of the list so I can remove it from state, what is the best React way of doing it? I'm not using any architecture at the moment.
Upvotes: 0
Views: 85
Reputation: 9073
Well let's saying you're using the item's key as an identifier for removal, in the child you'd have this:
var TodoItems = createClass ({
render:function(){
var listItem = this.props.items.map((item) =>{
return <li key={item.key}> {item.text} <button onClick={() => this.props.removeItem(item.key)} value={item.key}> x </button></li>
});
return <ul>
{listItem}
</ul>
}
});
And then in the parent:
removeItem:function(key){
this.setState({
items: this.state.items.filter(( obj )=> {
return obj.key !== key;
});
});
}
So in the child you're calling the property function with that item's key as an argument, then in the parent function you're removing all items with that key from the state items array (this uses ES6 as you can see)
In React you shouldn't mutate the state directly, but don't worry that set state call doesn't since filter
returns a new array
Upvotes: 1
Reputation: 8065
In your TodoItems, instead of set removeItem
directly to onClick
, you can call it with the item key inside an inline function which assigned to onClick
.
return <li key={item.key}> {item.text} <button onClick={()=>this.props.removeItem(item.key)} value={item.key}> x </button></li>
Upvotes: 1