पाठ 9 / 25

Updating Objects and Arrays Immutably

Make new copies, do not mutate.

React compares references

React decides whether state changed by comparing the old and new values with Object.is. If you mutate an array or object and pass the same reference to the setter, React sees no change and may skip the re-render, leaving the UI stale. Create new arrays and objects instead: spread ([...items, x], {...user, name}), map, filter, toSorted. Libraries like Immer let you write mutating-style code that produces copies.

Mutating versus copying state, run

I ran this with React 19.3 and react-dom 19.3 on Node.js 22, compiling JSX with esbuild 0.28. Browser-style examples use jsdom 29 as a fake DOM (imported from a small setup-dom.mjs file) and act() to apply updates. Pushing into the existing array and calling setItems with the same reference does not update the screen (still 1 item). Setting a new array afterwards re-renders, and the output now shows 3 items, including the one that was pushed earlier: hidden mutation creates confusing bugs.

import "./setup-dom.mjs";   // test setup: jsdom provides a browser-like DOM in Node
import { useState, act } from "react";
import { createRoot } from "react-dom/client";

function Todos() {
  const [items, setItems] = useState(["buy milk"]);
  return (
    <>
      <button id="mutate" onClick={() => { items.push("call mom"); setItems(items); }}>mutate</button>
      <button id="copy" onClick={() => setItems([...items, "pay bill"])}>copy</button>
      <p>{items.length} items: {items.join(", ")}</p>
    </>
  );
}
const root = createRoot(document.getElementById("root"));
await act(() => root.render(<Todos />));
await act(() => document.getElementById("mutate").click());
console.log("after mutating:", document.querySelector("p").textContent);
await act(() => document.getElementById("copy").click());
console.log("after copying :", document.querySelector("p").textContent);

Output:

after mutating: 1 items: buy milk
after copying : 3 items: buy milk, call mom, pay bill

Treat state as read-only

Never call push, splice, sort or assign properties on state; produce a new value and set it.

त्वरित जाँच: Why might mutating a state array not update the screen?

  • React forbids arrays
  • Arrays cannot be state
  • The reference is unchanged, so React sees no change
  • Mutation is too fast
Answer

The reference is unchanged, so React sees no change — New references signal changes.