Rendering Lists

`.map` Is How Arrays Become UI

Rendering Lists

Render arrays as JSX by mapping each item to a component or element. Every item needs a stable `key`.

4 min read Level 1/5 #react#lists#map
What you'll learn
  • Map arrays to JSX elements
  • Render lists of components
  • Recognize empty-state handling

Most lists in a React UI come from .map() — you transform an array of data into an array of JSX elements, and JSX renders arrays as a sequence of children.

The Pattern

function Tags() {
  const tags = ["js", "react", "frontend"];
  return (
    <ul>
      {tags.map(tag => (
        <li key={tag}>{tag}</li>
      ))}
    </ul>
  );
}

{ tags.map(...) } evaluates to an array of <li> elements. JSX renders each one.

Mapping to a Component

function TodoList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <TodoItem key={item.id} item={item} />
      ))}
    </ul>
  );
}

This is the bread-and-butter shape of React list views.

Empty States

[].map(...) renders nothing, which is usually wrong UX. Handle empty explicitly:

function TodoList({ items }) {
  if (items.length === 0) {
    return <p>No items yet.</p>;
  }
  return (
    <ul>
      {items.map(item => (
        <TodoItem key={item.id} item={item} />
      ))}
    </ul>
  );
}

Filtering and Mapping

You’ll often combine .filter with .map:

{todos.filter(t => !t.done).map(t => (
  <TodoItem key={t.id} todo={t} />
))}

With Indexes (Carefully)

.map exposes the index as a second argument:

{words.map((word, i) => (
  <li key={i}>{i + 1}. {word}</li>
))}

Inline vs Sub-Component

For trivial markup, render inline. For anything with its own state or several lines of JSX, pull it into a child component:

// Inline — fine
{names.map(n => <li key={n}>{n}</li>)}

// Sub-component — better when each item is complex
{users.map(u => <UserRow key={u.id} user={u} />)}

Up Next

That key prop matters more than it looks. Time to find out why.

Keys →