loliki
loliki

Reputation: 957

Reactjs pass children value to parent

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

Answers (2)

Jayce444
Jayce444

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

Tharaka Wijebandara
Tharaka Wijebandara

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

Related Questions