6
votes

I have child components that receive props from a parent, but on an event (button click) in a child I want to setState again with the new props. So the parent passes down all items in a list to the children. In the child prop a button deletes an item in the list. But how can you update the state so the list item is also removed from the view. This is my code:

const Parent = React.createClass({
    getInitialState:function(){
        return {
            items: []
        };
    },
    componentWillMount:function(){
        axios.get('/comments')
            .then(function(response) {
                this.setState({
                    items: response.data
                })
            }.bind(this));
    },
    render() {
        return (
            <div>
                <Child1 data={this.state.items}/>
            </div>
        );
    }
});

export default Parent;

export default function Child1(props){
    return(
        <div>
            { props.data.map((comment,id) =>(
                    <p key={id}>
                        {comment.name}<Delete data={comment.id}/>
                    </p>
                )
            )}
        </div>
    )
}

class Delete extends React.Component {
    constructor() {
        super();
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        Purchase.Action(this.props.data,'remove');
        axios.post('/comments', {
            item: this.props.data
        })
        .then(function (response) {
            console.log(response.data);     
        })
        .catch(function (error) {
            console.log(error);
        });
    }

    render() {
        return <Button onClick={this.handleClick}>Delete</Button>;
    }
}

module.exports = Delete;

So although the comment is deleted at the server, I want to delete the comment from the component view by updating the state.

1
You could pass down a function callback from the parent to child that the Child component can execute when an item is deleted. You can pass an id or whatever property you use to identify that item and then delete it from your array in your parent component using state. This would then call render() thus updating your view. - John F.

1 Answers

10
votes

If you want to delete the comment from the component, you have to update your Parent state.

In order to do that you can create a new method, delete(id), in your Parent component where you remove the deleted item from the state.

const Parent = React.createClass({
    getInitialState:function(){
        return {
            items: []
        };
    },
    componentWillMount:function(){
        this.setState({
            items: [
            {id: 1,name: "Name 1"},
            {id: 2,name: "Name 2"},
            {id: 3,name: "Name 3"}
          ]
        })
    },
    delete(id){
      // axios.post(...)
      let items = this.state.items.filter(item => item.id !== id);
      this.setState({items});
    },
    render() {
        return (
            <div>
                <Child1 
                   data={this.state.items} 
                   handleClick={this.delete} // Pass the method here
                />
            </div>
        );
    }
});

function Child1(props){
    return(
        <div>
            { props.data.map((comment,id) =>(
                    <p key={id}>
                        {comment.name}
                        <Delete 
                           data={comment.id}
                           handleClick={() => props.handleClick(comment.id)} // Pass the id here
                        />
                    </p>
                )
            )}
        </div>
    )
}

class Delete extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        return <button onClick={this.props.handleClick}>Delete</button>;
    }
}

jsfiddle