Reference equality compares whether two references identify the same object. React uses this comparison for state updates, so changing an object internally does not count when the reference stays unchanged. section 5.2.5 section 5.5
When storing arrays or objects in React state:
- Do not mutate the existing value and pass that same reference to the state setter. section 5.2.5
- Create and pass a new value so React can identify the state as changed. section 5.2.5
- Expect no re-render when the setter receives the identical value, even if an object was changed internally. section 5.5
Removing an item from a todo list
Avoid `todos.splice(index, 1); setTodos(todos)`, because the same array reference is passed back. Instead, derive a new array: `setTodos((value) => [...value.slice(0, index), ...value.slice(index + 1)])`. React can then detect the changed reference and render the shorter list. section 5.2.5
Listing 5.7 A proper to-do list application
import { useState } from "react";
function TodoApplication({ initialList }) {
const [todos, setTodos] = useState(initialList);
return (
<main>
{todos.map((todo, index) => (
<p key={todo}>
{todo}
<button
onClick={() => {
setTodos((value) => [ #1
...value.slice(0, index), #1
...value.slice(index + 1), #1
]);
}}
>
x
</button>
</p>
))}
</main>
);
}
function App() {
const items = ["Feed the plants", "Water the dishes", "Clean the cat"];
return <TodoApplication initialList={items} />;
}
export default App;
Browse the working todo-list implementation, which removes an item by constructing a new array rather than mutating the state array. section 5.2.5



