React Lists and Keys

Rendering lists in React is done with the JavaScript array map() method. You transform an array of data into an array of JSX elements, and React renders them all. Each element in the list needs a key so React can track it.

Rendering a List with map()

map() calls the function once for each item and returns a new array of <li> elements. JSX can render arrays directly.

const skills = ['React', 'Node.js', 'Laravel', 'MySQL'];

function SkillList() {
  return (
    <ul>
      {skills.map((skill) => (
        <li key={skill}>{skill}</li>
      ))}
    </ul>
  );
}
• React
• Node.js
• Laravel
• MySQL

Rendering a List of Objects

Real data is usually an array of objects, often from an API. Use a stable id from the data as the key.

const projects = [
  { id: 1, name: 'Portfolio', stars: 42 },
  { id: 2, name: 'Task Manager', stars: 17 },
];

function Projects() {
  return (
    <ul>
      {projects.map(({ id, name, stars }) => (
        <li key={id}>
          {name} ★ {stars}
        </li>
      ))}
    </ul>
  );
}
• Portfolio ★ 42
• Task Manager ★ 17

Why React Needs Keys

Keys tell React which item is which between renders. When items are added, removed or reordered, React uses keys to update only what changed and to keep each item's state attached to the right item.

  • Keys must be unique among siblings, not across the whole app.
  • Keys should be stable: the same item gets the same key every render.
  • Avoid array indexes as keys when the list can be reordered, filtered or edited.
  • Never generate keys with Math.random() during render.
  • The key goes on the outermost element returned from map().

Filtering a List

Chain filter() before map() to show only some items.

const tasks = [
  { id: 'a', text: 'Write tests', done: true },
  { id: 'b', text: 'Deploy app', done: false },
  { id: 'c', text: 'Update docs', done: false },
];

function TodoList() {
  const pending = tasks.filter((t) => !t.done);
  return (
    <ul>
      {pending.map((t) => <li key={t.id}>{t.text}</li>)}
    </ul>
  );
}
• Deploy app
• Update docs

Extracting a List Item Component

For complex items, move the markup into its own component. The key stays on the component in the map call, not inside it: {users.map(u => <UserRow key={u.id} user={u} />)}.

Frequently asked questions

Why do I get the warning "Each child in a list should have a unique key prop"?

You rendered an array without giving each element a key. Add key={item.id} (or another unique, stable value) to the outermost element returned from map().

Can I use the index as a key in React?

Only if the list is static and never reordered, filtered or edited. Otherwise index keys can cause wrong items to update and inputs to lose their values.

Can I use forEach instead of map in React?

No, because forEach returns undefined. map() returns a new array of elements that JSX can render.