Site icon Ampersand Tutorials

React Lists and Keys: Render Arrays the Right Way (2026)

Quick answer: Render collections in React by mapping an array to components: {items.map(item => <li key={item.id}>{item.name}</li>)}. The key prop is mandatory — a stable, unique identifier (usually a database ID) that lets React track each item across re-renders. Skip keys and you get console warnings plus subtle, painful bugs where inputs or animations attach to the wrong rows. This guide covers the pattern, the key rules, and why index keys break things.

The map-to-JSX pattern

function CourseList() {
  const courses = [
    { id: 1, title: 'React Basics', lessons: 12 },
    { id: 2, title: 'React Hooks', lessons: 8 },
    { id: 3, title: 'TypeScript with React', lessons: 15 },
  ];

  return (
    <ul>
      {courses.map(course => (
        <li key={course.id}>
          {course.title} — {course.lessons} lessons
        </li>
      ))}
    </ul>
  );
}

Any JavaScript expression works inside JSX braces, and .map() returns an array of elements, which React renders inline. Filter before mapping for search results: courses.filter(c => c.title.includes(query)).map(...). Combining filter and map covers half of all real UI list work.

The rules of keys

RuleWhy it matters
Unique among siblingsKeys only need to distinguish items in the same list — not globally
Stable across rendersReact matches old and new trees by key; changing keys destroys and recreates components
Never the array index (for mutable lists)Index keys make React mispair state with rows after insert/delete — the “typing in the wrong input” bug
Extract during mapKeys go on the outermost element inside the map callback, not inside the component

When your data genuinely has no IDs, generate one once when the data loads (for example crypto.randomUUID()) and store it — do not reach for the index. If the list is strictly static (never reordered, never edited), index keys are tolerable, but the habit is safer to avoid.

The index-key bug, concretely

Imagine a to-do list rendered with index keys. You type into the first item’s inline edit field, then delete an item above it. React thinks “key 0 still exists” and pairs your still-focused input with the different todo that is now at index 0 — your text appears on the wrong row. With ID keys, React knows exactly which component died and which survived; your input follows its item. The same bug corrupts animations, transitions, and any per-row state.

Empty states and fragments

{courses.length === 0 ? (
  <p>No courses match your search.</p>
) : (
  courses.map(c => <CourseCard key={c.id} {...c} />)
)}

Two extras in one line: the spread {...c} passes every property as a prop, and the ternary gives an empty state — which real apps always need. Returning multiple elements from map or conditional rendering requires either a wrapper div or a fragment (<>...</>), which groups without adding a DOM node.

With lists mastered you can display anything; the final piece of core interactivity is reacting to users — forms and events, next in the series: React events and forms.

To build these habits with live code review, Ampersand Academy teaches React one-to-one, from first component to complete apps.

Frequently asked questions

What are keys in React lists?

Keys are unique identifiers you give each item when rendering an array of components. React uses them to match items across renders, preserving component state and DOM nodes correctly when the list changes.

Why should I not use the array index as a key?

Index keys break when items are inserted, deleted or reordered: React pairs old state with the wrong rows, causing the classic bugs of text appearing in the wrong input or animations attaching to the wrong item. Use a stable ID from the data instead.

How do I render an array of objects in React?

Use the map method inside JSX braces: items.map(item => ). Filter before mapping for search or category views.

Where exactly does the key prop go?

On the outermost element returned inside the map callback – the direct child of the list container. Putting the key inside the component itself does nothing, because React reads keys from the list position.

Do keys need to be globally unique?

No. Keys only need to be unique among their siblings in the same list. The same ID can safely appear in two different lists on one page.

Exit mobile version