Filip
Filip

Reputation: 955

Filtering array of objects by object property does not work in ReactJS

I want to delete an object from an array by a generated object id.

I've already tried multiple solutions on this and nothing is working.

Handler function:

  handleDeleteTask = id => {
    const task = this.state.tasks.find(i => {
      return i.id === id;
    });

    const newTasks = this.state.tasks.splice(task, 1);
    this.setState({ tasks: newTasks });
  };

JSX:

  {this.state.tasks.map(task => {
          return (
            <Task
              key={task.id}
              task={task.text}
              title={task.title}
              deleteTask={() => this.handleDeleteTask(task.id)}
            />
          );
      })}

Upvotes: 1

Views: 65

Answers (2)

Josh Rutherford
Josh Rutherford

Reputation: 2723

The first problem is, Array.prototype.splice needs the index of the item you want to delete as the first argument, not the item itself. To find the index instead, change this.state.tasks.find to this.state.tasks.findIndex.

The second problem is splice returns the removed portion of the array, not the new array, so you'd be setting your state to include just the removed item.

Perhaps a simpler approach would be to use Array.prototype.filter to remove the undesired item.

handleDeleteTask = id => {
    this.setState({
        tasks: this.state.tasks.filter(it => it.id !== id)
    })
}

Upvotes: 2

Dupocas
Dupocas

Reputation: 21357

Edited to reflect the suggestions from comments

splice returns the removed part. You could use filter instead:

  handleDeleteTask = id => {

    const newTasks = [...this.state.tasks].filter(x => x.id !== id);
    this.setState({ tasks: newTasks });
  };

Or spread the original state, splice the copy and set it as new state

  handleDeleteTask = id => {
    const task = this.state.tasks.findIndex(i => {
      return i.id === id;
    })

    const newTasks = [...this.state.tasks]
    newTasks.splice(task, 1)
    this.setState({ tasks: newTasks });
  };

Actually this could be written in one single line

const removeById = id => this.setState({tasks: [...this.state.tasks].filter(x=> x.id !== id)})

Upvotes: 4

Related Questions