React Lists

Rendering lists in React means turning an array of data into an array of JSX elements, most often with the array's map method.

Rendering Arrays with map

JSX can't loop with a for statement directly, but because map returns a new array, you can call it right inside curly braces to transform an array of data into an array of elements. React then renders each element in the returned array in order.

A Simple Fruit List

function FruitList({
  fruits = [
    { id: 1, name: 'Apple' },
    { id: 2, name: 'Mango' },
  ],
}) {
  return (
    <ul>
      {fruits.map((fruit) => (
        <li key={fruit.id}>{fruit.name}</li>
      ))}
    </ul>
  );
}

export default FruitList;

// fruits = [{ id: 1, name: 'Apple' }, { id: 2, name: 'Mango' }]

Why the key Prop Matters

The key prop isn't a regular prop your component receives — React uses it internally to track which array item corresponds to which rendered element across re-renders. Stable, unique keys let React reuse existing DOM nodes and component state instead of tearing everything down and rebuilding it whenever the list changes.

Keyed Comments List

function CommentList({
  comments = [
    { id: 1, author: 'Ana', text: 'Great post!' },
    { id: 2, author: 'Ben', text: 'Thanks for sharing.' },
  ],
}) {
  return (
    <ul>
      {comments.map((comment) => (
        <li key={comment.id}>
          <strong>{comment.author}: </strong>
          {comment.text}
        </li>
      ))}
    </ul>
  );
}

export default CommentList;
Note: Avoid using the array index as a key if the list can be reordered, filtered, or have items inserted in the middle. Index keys cause React to match the wrong old element to the wrong new item, which can mix up input values and component state.

Filtering and Transforming Before Rendering

Because map, filter, and sort all return new arrays, you can chain them together before rendering to derive exactly the list you want — for example showing only incomplete tasks, sorted by due date — without mutating the original array or storing the derived list in state.

Filtering and Sorting Together

function ActiveTasks({
  tasks = [
    { id: 1, title: 'Write report', done: false, dueDate: 3 },
    { id: 2, title: 'Clean inbox', done: true, dueDate: 1 },
    { id: 3, title: 'Plan sprint', done: false, dueDate: 2 },
  ],
}) {
  const incomplete = tasks
    .filter((task) => !task.done)
    .sort((a, b) => a.dueDate - b.dueDate);

  return (
    <ul>
      {incomplete.map((task) => (
        <li key={task.id}>{task.title}</li>
      ))}
    </ul>
  );
}

export default ActiveTasks;
Key ChoiceSafe WhenRisky When
Unique id from data (item.id)Always — the recommended defaultNever
Array indexList is static and never reorders/filtersList items can be added, removed, or reordered
Randomly generated on each renderNeverAlways — breaks React's matching entirely
  • Give every list item a key prop that is unique among its siblings.
  • Prefer a stable id from your data over the array index.
  • Put the key on the outermost element returned inside map, not on a child deeper in the tree.
  • Chain filter/sort/map to compute derived lists instead of storing duplicate data in state.

Exercise: React Lists

What method is commonly used to render an array of data as a list of JSX elements?