Identity: position, type, key

React chapter 140 · Reconciliation · lists · where state lives · source: react.dev/learn/preserving-and-resetting-state

The problem

A list of people, each row with its own note. The rows use key={index}. Remove the first person and every note slides onto the wrong person, because React matched old and new rows by position.

The pattern that fixes it

State belongs to a component’s place in the tree, and key is how you name that place. With key={person.id} React matches rows by identity: the removed row’s state is destroyed and every other note stays with its owner.

In plain words

React does not know which row is “Ada”. It only sees “first row, second row…”. A key is a name tag that lets React recognise the same item after the list changes.

Coats on numbered hooks. If the first coat leaves and everyone shifts one hook left without name tags, the cloakroom hands you someone else’s coat.

Terms

reconciliation
React comparing the new tree to the previous one to decide what to keep, update or recreate.
identity
Same component type in the same position (and with the same key) = the same instance, keeping its state.
key
A stable, unique id among siblings that tells React which item is which.

Going deeper

The three rules React uses

1) Different type at a position (div → span, A → B): destroy the subtree and its state, mount fresh. 2) Same type: keep the instance, update props. 3) Among siblings, match by key when present, else by index. That is the whole algorithm, and it is O(n) because React never searches for moved subtrees without keys.

Index keys are fine… sometimes

If the list never reorders, inserts or deletes in the middle, and rows have no state or uncontrolled inputs, index keys work. The moment any of that is false, they silently attach state to the wrong item. Random keys (Math.random()) are worse: every render remounts everything.

Using identity on purpose

Because a new key means a new instance, <Form key={userId} /> resets a form when the user changes (chapter 93). And defining a component inside another component creates a new type each render, which remounts it every time (chapter 92).

Keep learning

More courses

  • Jobs, linked to lessons — Browse jobs where every requirement links to the chapter that teaches it. See how ready you are, how long the gap takes to close, and which listings look stale.
  • Match a job post to courses — Paste a job post. Each skill is matched to a track here and put in learning order, foundations first.
  • Database in depth — How a query becomes work. Indexes, isolation, locks, and the plans that explain why a page is slow — not an ORM tour.
  • System Design — Eight interview case studies, from a flash sale and Tatkal to a live final and a chat model, plus JWT in separate chapters.
  • Microservices — Microservice patterns one diagram at a time: how to split a monolith, how services talk, and how data stays consistent without distributed transactions.
  • Kafka — A beginner-to-senior path through event logs, reliable delivery, production operations, and disaster recovery.
  • Frontend system design — How a UI is sliced when it is a product, not a page: ownership of state, cache, routes, and what happens when the network lies.
  • CSS in depth — See the box, then the page. Visual chapters from the box model through Flexbox surprises, Grid, selectors, and units, then backgrounds, shapes, and visual effects, each with a playground.
  • Accessibility — HTML labs first, then a full pass of WAI-ARIA 1.3: naming, every state, widget and structure roles, live regions, ariaNotify, and relationships.
  • Docker — What an image is, why layers cache, and how containers find each other on a network.
  • Redis — Fifteen Redis patterns, one picture each: cache, session, lock, counter, rate limiter, queue, and when Redis is the wrong tool.