Rendering Lists

Most apps display collections — product lists, search results, chat messages. React renders lists using .map() and requires a key prop.

Basic list rendering

JSX
function TodoList({ todos }) {
  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>
          {todo.text} {todo.done ? '✅' : '⬜'}
        </li>
      ))}
    </ul>
  );
}

Keys — Why they matter

JSX
// ❌ Bad — using array index as key
{todos.map((todo, index) => (
  <TodoItem key={index} todo={todo} />
))}

// ✅ Good — using stable, unique IDs
{todos.map(todo => (
  <TodoItem key={todo.id} todo={todo} />
))}

Keys help React identify which items changed, were added, or removed. When keys change, React unmounts and remounts the component — which destroys local state. Use stable IDs (database IDs, UUIDs).

Filtering

JSX
function ActiveTodos({ todos }) {
  const active = todos.filter(t => !t.done);

  return (
    <ul>
      {active.map(todo => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
}

Sorting

JSX
function SortedList({ items }) {
  const sorted = [...items].sort((a, b) => a.name.localeCompare(b.name));

  return (
    <ul>
      {sorted.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}

Empty states

JSX
function TodoList({ todos }) {
  if (todos.length === 0) {
    return <p>No todos yet. Add one above!</p>;
  }

  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
}

Tips

  • Always use stable, unique keys — database IDs are ideal.
  • Never use Math.random() for keys — they change on every render.
  • Never use array indices as keys if the list can reorder.
  • Handle empty states — users shouldn't see a blank screen.

Next: forms.