Objects and Arrays in State

Never Mutate State

React re-renders only when you give it a new object or array. Copy with the spread operator and change the copy.

Example

import { useState } from 'react';

export default function App() {
  const [user, setUser] = useState({ name: 'Asha', city: 'Pune' });
  const [todos, setTodos] = useState(['Learn JSX']);
  return (
    <div>
      <p>{user.name} lives in {user.city}</p>
      <button onClick={() => setUser({ ...user, city: 'Delhi' })}>Move to Delhi</button>
      <button onClick={() => setTodos([...todos, 'Todo ' + (todos.length + 1)])}>Add todo</button>
      <button onClick={() => setTodos(todos.slice(0, -1))}>Remove last</button>
      <ul>{todos.map((t) => <li key={t}>{t}</li>)}</ul>
    </div>
  );
}

Result

Array Update Cheatsheet

ActionDo (new array)Avoid (mutates)
add[...arr, item]push
removearr.filter(x => x.id !== id)splice
updatearr.map(x => x.id === id ? { ...x, done: true } : x)arr[i].done = true
sort[...arr].sort()arr.sort()