简体   繁体   中英

How to delete object from array using object property - React

I have a todo list that holds a delete button in a grandchild, that when clicked fires an event in the parent - I am wanting this event to delete the array entry corresponding to the grandchild clicked.

Parent (contains the array and my attempt at the function)

const tasks = [
  { name: 'task1', isComplete: false },
  { name: 'task2', isComplete: true },
  { name: 'task3', isComplete: false },
]

// taskToDelete is the name of the task - doesn't contain an object
deleteTask(taskToDelete) {
    this.state.tasks.remove(task => task.name === taskToDelete);
    this.setState({ tasks: this.state.tasks });

}

Any help would be appreciated

Two issues there:

  1. You're seeming to try to direct modify this.state.tasks . It's important not to do that, never directly modify this.state or any object on it. See "Do Not Modify State Directly" in the React documentation for state .

  2. You're passing an object to setState that is derived from the current state. It's important never to do that, too. :-) Instead, pass setState a function and use the state object it passes you when calling that function. From "State Updates May Be Asynchronous" in the documentation :

    Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state ... [Instead]...use a second form of setState() that accepts a function rather than an object.

    (my emphasis)

I figure your remove on an array was intended to be hypothetical, but for the avoidance of doubt, arrays don't have a remove method. In this case, the best thing to do, since we need a new array, is to use filter to remove all entries that shouldn't still be there.

So:

deleteTask(taskToDelete) {
    this.setState(prevState => {
        const tasks = prevState.tasks.filter(task => task.name !== taskToDelete);
        return { tasks };
    });
}

You could simply filter the array :

this.setState(prevState => ({
    tasks: prevState.tasks.filter(task => task.name !== 'taskToDelete')
}));

Also when updating based on this.state , its better to use the function form because setState is async .

You can use filter to remove one object from an array following the immutable pattern (filter will create a new array) :

deleteTask(taskToDelete) {
    const newTaskArray = this.state.tasks.filter(task => task.name !== taskToDelete);
    this.setState({ tasks: newTaskArray });

}

Edit : codepend of the solution : https://codepen.io/Dyo/pen/ZvPoYP

You can implement deleteTask method as below:

deleteTask(taskToDelete) {
  this.setState((prevState, props) => {
    const tasks = [...prevState.tasks];
    const indexOfTaskToDelete = tasks.findIndex(
      task => task.name === taskToDelete
    );
    tasks.splice(indexOfTaskToDelete, 1);
    return { tasks };
  });
}

A. Find the index of taskToDelete .

B. Then use splice method to delete the item from the collection

C. Then call setState to update the state with tasks .

You can use higher order function Array#filter to delete the task.

let updatedTasks  =     this.state.tasks.filter(task => task.name !== taskToDelete);

this.setState({ tasks: updatedTasks });

I have followed below steps to delete a particular selected Object from the state array:

Here I am using a list of checkBoxes, when I am selecting a checkBox it will add it in the state array and when it gets de-selected then it will get deleted from the array.

if (checked) {
            var tempObject = { checkboxValue: data, label: title }
            this.state.checkBoxState.push(resTemp);
        } else {
            var element = data; //data is coming from different method.
            for (let index = 0; index < this.state.checkBoxState.length; index++) {
                if (element === this.state.checkBoxState[index].checkboxValue) {
                    this.state.checkBoxState.splice(index, 1);
                }
            }
        }

I got stuck for this question and I am sharing my solution. Hope it will help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM