A Look Behind the Scenes of React & Optimization TechniquesEntry 7 of 10

Keys: Lists, State Position, and Resetting State

A key gives an element a stable identity so React can match it between renders.

Notes

  • State is tied to position. React associates a component's state with its position in the tree (and its type). If items in a list shift, state can end up attached to the wrong item.
  • Keys fix that. With a key, React matches components by key instead of position. Use a stable, unique ID from the data. Avoid array indexes when items can be reordered, inserted, or removed.
  • Changing a key resets state. When a component's key changes, React throws away the old instance and mounts a fresh one with fresh state. This is the clean way to "reset" a component, and it avoids syncing props into state with an effect.

What / Why / When

What

Identity hints for React's reconciliation.

Why

Correct state per item, efficient list updates, and easy resets.

When

Every list rendered with map(), and any component whose state should reset when some value changes.

Use case

Resetting Counter whenever a new start value is chosen.

Code compare

React
// Lists: a stable key from the data<ul>  {players.map((p) => (    <li key={p.id}>{p.name}</li>  ))}</ul>​// Reset: a new chosenCount gives Counter a new key, so it remounts with fresh state<Counter key={chosenCount} initialCount={chosenCount} />

Lists use track in @for, which is required and plays the same role as key:

Angular
@for (p of players(); track p.id) {<li>{{ p.name }}</li>}

There is no key prop for resetting a single component. The idiomatic approach is to derive resettable state from the input with linkedSignal(), as in the CounterComponent in Entry 3. To fully re-create a component, a one-item @for works:

Angular
@for (count of [chosenCount()]; track count) {<app-counter [initialCount]="count" />}

Differences and gotchas

  • Angular made track mandatory in @for, so forgetting it is a compile error. React only warns in the console about missing keys.
  • track $index in Angular has the same problems as index keys in React for reorderable lists.

Quick reference

ReactAngular
key={item.id} in map()track item.id in @for
Change key to reset a componentlinkedSignal() or one-item @for