简体   繁体   中英

How do I update an array of objects in component state?

I am trying to update the property of an object which is stored in an array.

my state looks something like this:

state = {
  todos: [
    {
     id: '1',
     title: 'first item,
     completed: false
    },
    {
     id: '2',
     title: 'second item,
     completed: false
    }
  ],
}

What I am trying to do is access the second element in the 'todos' array and update the completed property to either false -> true or true -> false.

I have a button with the handler for update, and my class method for the update looks like this:

onUpdate = (id) => {
  const { todos } = this.state;
  let i = todos.findIndex(todo => todo.id === id);
  let status = todos[i].completed
  let updatedTodo = {
    ...todos[i],
    completed: !status
  }
  this.setState({
    todos: [
      ...todos.slice(0, i),
      updatedTodo,
      ...todos.slice(i + 1)
    ]
  });
}

While this does work, I want to find out if there is a more concise way of achieving the same result; I tried to use Object.assign(), but that didn't work out because my 'todos' is an array, not an object. Please enlighten me with better code!

You can simply copy your todos from state , then make edits, and after that put it back to the state

onUpdate = (id) => {
    var todos = [...this.state.todos]
    var target = todos.find(todo => todo.id == id)
    if (target) {
        target.completed = !target.completed
        this.setState({ todos })
    }
}

It would be best to use update function to make sure you don't work on outdated data:

onUpdate = (id) => {
  this.setState(prevState => {
    const copy = [...prevState.todos];
    const index = copy.findIndex(t => t.id === id);
    copy[index].completed = !copy[index].completed;

    return { todos: copy }
  })  
}

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