When reading React Cookbook I've stumbled upon a code snippet, this function gets called when user checks a task as completed in a TODO list:
markAsCompleted = id => {
// Finding the task by id...
const foundTask = this.state.items.find(task => task.id === id);
// Updating the completed status...
foundTask.completed = true;
// Updating the state with the new updated task...
this.setState({
items: [
...this.state.items,
...foundTask
]
});
}
UPD: Somehow I've completely missed the spread operator on foundTask. So what's really happening is the state gets updated with only ...this.state.items (which was mutated), and the ...foundTask part does not go into state, since it's not a valid spread.
At first it looked like it should add a new element to the items array, instead of updating, so I went to the JS console to check:
state = { items: [{id: '0', done: false}, {id: '1', done: false}] }
upd = state.items.find(obj => obj.id === '0') // {id: "0", done: false}
upd.done = true // also updates object inside the array
state = { items: [...state.items, upd] }
/* Indeed, adds a new element:
items: Array(3)
0: {id: "0", done: true}
1: {id: "1", done: false}
2: {id: "0", done: true}
*/
So then I've downloaded the code and ran it locally. And, to my surprise, it worked! State was getting updated without any trouble, no extra elements appeared. I used React DevTools to see the live state while testing.
I searched the web, but couldn't find any examples like in the book, but with a better explanation. Usually all solutions involve using .map() to build a new array, and then replace an existing one (e.g. https://stackoverflow.com/a/44524507/10304479).
The only difference I see between the book code snippet and console test is that React is using .setState(), so maybe this helps somehow. Can anyone help to clarify, why is it working?
Thanks!