Object & Array State Object and Array State
Last updated: 2026-11-02
Object & Array State Object and Array State
State must be replaced with a new object or a new array before React notices an update: use the spread operator to override a field on objects, and use spread, map or filter to build a new array for lists. Mutating in place leaves the reference untouched, so React sees no change and the interface does not update. Immutable updates are the rule every React developer keeps relearning.
| Group | Rendering & State |
|---|---|
| Kind | Pattern |
| Since | React 16.8 |
ℹ️ Info The editor transpiles JSX to JavaScript and renders the real UI in a sandbox; components mount automatically — no manual render call needed.
📝 Syntax
setUser({ ...user, name: 'New name' }) // Object: spread and override
setList([...list, newItem]) // Array: spread and append
setList(list.filter((x) => x.id !== id)) // Array: filter to remove
Returns:No return value — a coding convention and mental model.
▶ Example
The example runs out of the box: it auto-renders when expanded, and edits take effect instantly.
Output:
The name "Alice" and the tag "React" are shown; clicking the rename button turns the name into "Bob", and clicking the add-tag button appends one more "Hooks" tag each time — every update happens by creating a new object.
💡 Key Points
⚠️ Warning user.name = 'x' or user.tags.push(...) does not trigger a re-render: the reference stays the same, so React believes nothing changed.
💡 Tip Spread nested objects layer by layer: setUser({ ...u, addr: { ...u.addr, city: 'Shanghai' } }); spreading only the outer level is not enough.
ℹ️ Info Keeping the structure flat and the states independent removes a lot of the boilerplate that comes from spreading new objects layer by layer.
🏷️ More Rendering & State
💡 Related Cases
More case studies coming soon.
📚 Related Tutorials
❓ FAQ
Q Why does changing an object state not update the page?
A React compares the old and new references with Object.is: an in-place mutation keeps the reference, so the state counts as unchanged. You must create a new object with the spread operator and pass it to setState.
Q How do I update nested object state correctly?
A Spread from the level you change all the way out to the top: setUser({ ...user, addr: { ...user.addr, city: 'Shanghai' } }), keeping every untouched reference intact.
Q How do I add and remove items in an array state?
A Append with [...list, item] or prepend with [item, ...list]; remove with filter((x) => x.id !== id). Both return a new array.