简体   繁体   中英

React: why is that mutating the state leaves the component in such a weird state

First, let me preemptively address this by saying that I know that we should not mutate the state. I just wanted to explore what exactly would go wrong if we mutate the state directly.

Here I built a simple todo app. The todo items are stored in an array. eg [{id: 0, name: 'foo'}, {id: 1, name: 'bar'}]

To remove one todo item from the list, I think what we should do, ie the immutable way is to filter out that todo item from the list and return a copy of a new list. ie

setTodos((prevTodos) => prevTodos.filter((todo) => todo.id !== id));

But I was thinking that, this can be slow because it is a O(n) process. If we knew every todo item's index in the list and we can just do constant time lookup to find that item from the list and set it to null or something.

One way to achieve this is to have a count variable starting from 0 and we use that as the id for each todo item and we increment the count every time we add a new todo. In this case, the id would be equal to the numeric index corresponding to the position the todo item has in the list. and we just grab that id and update the list directly.

todos[id] = null;

However this leaves the component in a weird state, every time I remove one item, the list is actually going to be added a one todo.

For example, before we have [{id: 0, name:'foo'}] after we do todos[0] =null , we will end up with [null, {id: 1, name:''}]

Here is a live demo you can play with https://codesandbox.io/s/react-todo-mutate-e0zj3?file=/src/App.js

Can someone point out how exactly this bug happened?

Again I know mutating the state is not the right way to go but I just wanted to understand React more deeply so I made this little experiment.

This is not react behavior :). Buttons have implicit type="submit". So clicking on delete button you are submitting form (adding new todo, and setting null at some index in array)

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