If we want to use arrays or objects in our React state, we have to create a copy of the value before modifying it. This is a cheat sheet on how to do add, remove, and update items in an array or object within the context of managing React state.
Arrays
const [todos, setTodos] = useState([]);
Add to array
const handleAdd = (todo) => {
const newTodos = todos.slice();
newTodos.push(todo);
setTodos(newTodos);
}
The spread operator is syntactic sugar for creating a new copy of a reference.
const handleAdd = (todo) => {
const newTodos = [...todos];
newTodos.push(todo);
setTodos(newTodos);
}
We can also use the spread operator to create copy and append an item with the following syntax:
const handleAdd = (todo) => {
setTodos([...todos, todo]);
}
Remove from array
const handleRemove = (todo) => {
const newTodos = todos.filter((t) => t !== todo);
setTodos(newTodos);
}
Update array
const handleUpdate = (index, todo) => {
const newTodos = [...todos];
newTodos[index] = todo;
setTodos(newTodos);
}
Objects
const [todos, setTodos] = useState({});
Add to object
const handleAdd = (todo) => {
const newTodos = Object.assign({}, todos);
newTodos[todo.id] = todo;
setTodos(newTodos);
}
We can use spread operator to create shallow copy as well.
const handleAdd = (todo) => {
const newTodos = {...todos};
newTodos[todo.id] = todo;
setTodos(newTodos);
}
Similar to arrays, there's a shortcut for doing this in one line:
const handleAdd = (todo) => {
setTodos({...todos, [todo.id]: todo});
}
Remove from object
const handleRemove = (todo) => {
const newTodos = {...todos}
delete newTodos[todo.id]
setTodos(newTodos);
}
Update object
Same as adding, it will overwrite the value if the key already exists.
const handleUpdate = (todo) => {
setTodos({...todos, [todo.id]: todo});
}
Top comments (13)
Can you also add how to update array of objects
I agree
Just wrote How to update an array of objects in React state
This is a brilliant little recap for objects and arrays. Nicely done
For deleting key and value from object I prefer rest operator:
Signed up just to comment. This is so well set up and explained.
Most people would just put in the one-liners without explaining what they are doing at all.
🤙
Edit:
Thanks for this cheatsheet, nice to have it open when fighting with array states.
Mh, i learned to always get the old state like (dont focus on typos, just sketching):
const handleAdd = (todo) => {
setTodos((oldTodos) => {
return [...oldTodos, todo]
})
}
Why you dont use this?
Or is this approach only needed, if the new value depends on the old one?
would also be curious about the answer - but i think your approach is not a bad approach - just different. Why the author didnt took this into account would be inetersting ...
Great article and recap : P
Magnifico hermano <3
In this snippet, the 'id' property is in brackets. Is this React syntax or some type of destructuring?
const handleAdd = (todo) => {
setTodos({...todos, [todo.id]: todo});
}
isn't this mutation?
const newTodos = [...todos];
newTodos[index] = todo;
The spread operator [...] creates a shallow copy and thus doesn't mutate the original state directly.