DEV Community

Andrew Lee
Andrew Lee

Posted on

Cheat Sheet for Updating Objects and Arrays in React State

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([]);
Enter fullscreen mode Exit fullscreen mode

Add to array

const handleAdd = (todo) => {
  const newTodos = todos.slice();
  newTodos.push(todo);
  setTodos(newTodos);
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

We can also use the spread operator to create copy and append an item with the following syntax:

const handleAdd = (todo) => {
  setTodos([...todos, todo]);
}
Enter fullscreen mode Exit fullscreen mode

Remove from array

const handleRemove = (todo) => {
  const newTodos = todos.filter((t) => t !== todo);
  setTodos(newTodos);
}
Enter fullscreen mode Exit fullscreen mode

Update array

const handleUpdate = (index, todo) => {
  const newTodos = [...todos];
  newTodos[index] = todo;
  setTodos(newTodos);
}
Enter fullscreen mode Exit fullscreen mode

Objects

const [todos, setTodos] = useState({});
Enter fullscreen mode Exit fullscreen mode

Add to object

const handleAdd = (todo) => {
  const newTodos = Object.assign({}, todos);
  newTodos[todo.id] = todo;
  setTodos(newTodos);
}
Enter fullscreen mode Exit fullscreen mode

We can use spread operator to create shallow copy as well.

const handleAdd = (todo) => {
  const newTodos = {...todos};
  newTodos[todo.id] = todo;
  setTodos(newTodos);
}
Enter fullscreen mode Exit fullscreen mode

Similar to arrays, there's a shortcut for doing this in one line:

const handleAdd = (todo) => {
  setTodos({...todos, [todo.id]: todo});
}
Enter fullscreen mode Exit fullscreen mode

Remove from object

const handleRemove = (todo) => {
  const newTodos = {...todos}
  delete newTodos[todo.id]
  setTodos(newTodos);
}
Enter fullscreen mode Exit fullscreen mode

Update object

Same as adding, it will overwrite the value if the key already exists.

const handleUpdate = (todo) => {
  setTodos({...todos, [todo.id]: todo});
}
Enter fullscreen mode Exit fullscreen mode

Top comments (13)

Collapse
 
arunkumar413 profile image
Arun Kumar

Can you also add how to update array of objects

Collapse
 
tombohub profile image
tombohub

I agree

Collapse
 
andyrewlee profile image
Andrew Lee
Collapse
 
93alan profile image
Alan Montgomery

This is a brilliant little recap for objects and arrays. Nicely done

Collapse
 
perpetualwar profile image
Srđan Međo • Edited

For deleting key and value from object I prefer rest operator:

const handleRemove = (todo) => {
  const {[todo]: filteredOutValue, ...newTodos} = todos;
  setTodos(newTodos)
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
chamabreu profile image
Jan Manuel Brenner • Edited

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?

Collapse
 
hkiepe profile image
Henrik Kiepe

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 ...

Collapse
 
viktorms profile image
ViktorMS

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.

🤙

Collapse
 
krm218 profile image
Ken Mau

Great article and recap : P

Collapse
 
ace540i profile image
Michael Darretta

isn't this mutation?

const newTodos = [...todos];
newTodos[index] = todo;

Collapse
 
brianl09 profile image
brianL09

The spread operator [...] creates a shallow copy and thus doesn't mutate the original state directly.

Collapse
 
jakeborromeo profile image
Jake Borromeo

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});
}

Collapse
 
walidzhani profile image
Walid Zhy7

Magnifico hermano <3