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:
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 ...
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.
🤙
Great article and recap : P
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.
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});
}
Magnifico hermano <3