`.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`.
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.