Skip to content

React Tutorial Props and Data

Using map() in React to Render Elements

Lesson 39 of 156 1 min read By Deepak Paswan Updated Oct 10, 2026

Runnable lesson · press Try it on the examples to edit and run them here.

Array.prototype.map is the workhorse of React lists. It takes an array and returns a new array of the same length, built by calling a function on each item. If you need a refresher, read Array map.

map returns elements

App.jsx
JSX
function App() {
  const numbers = [1, 2, 3];
  const doubled = numbers.map((n) => n * 2);
  return <p>{doubled.join(", ")}</p>;
}

In React, the callback returns JSX instead of numbers, so you get an array of elements, which React displays.

The arrow function and the parentheses

App.jsx
JSX
function App() {
  const names = ["Ada", "Grace"];
  return (
    <ul>
      {names.map((name) => (
        <li key={name}>{name}</li>
      ))}
    </ul>
  );
}

Two syntaxes work, and they are a common cause of “nothing renders”:

App.jsx
JSX
// Parentheses: implicit return of the JSX
names.map((name) => (
  <li key={name}>{name}</li>
))

// Curly braces: you MUST write return
names.map((name) => {
  return <li key={name}>{name}</li>;
})

If you use curly braces and forget return, map produces an array of undefined values and the list is empty.

The index argument

map passes the position as a second argument:

App.jsx
JSX
function App() {
  const names = ["Ada", "Grace", "Linus"];
  return (
    <ol style={{ listStyle: "none", padding: 0 }}>
      {names.map((name, index) => (
        <li key={name}>{index + 1}. {name}</li>
      ))}
    </ol>
  );
}

The index is good for display (numbering, striping rows). Do not use it as a key when the list can change; see Understanding React Keys.

Transform while mapping

Map is also how you turn data into a different shape before rendering:

App.jsx
JSX
function App() {
  const people = [
    { id: 1, first: "Ada", last: "Lovelace" },
    { id: 2, first: "Grace", last: "Hopper" },
  ];
  const fullNames = people.map((p) => `${p.first} ${p.last}`.toUpperCase());
  return (
    <ul>
      {fullNames.map((n) => <li key={n}>{n}</li>)}
    </ul>
  );
}

Nested lists

Map inside map works. Give every level its own keys:

App.jsx
JSX
function App() {
  const groups = [
    { id: "fe", title: "Frontend", skills: ["HTML", "CSS", "React"] },
    { id: "be", title: "Backend", skills: ["PHP", "MySQL"] },
  ];
  return (
    <div>
      {groups.map((g) => (
        <section key={g.id}>
          <h3>{g.title}</h3>
          <ul>
            {g.skills.map((s) => <li key={s}>{s}</li>)}
          </ul>
        </section>
      ))}
    </div>
  );
}

Do the data work before the JSX

filter, sort and slice come before map. If the line gets long, put the prepared array in a variable:

App.jsx
JSX
function App() {
  const products = [
    { id: 1, name: "Mouse", inStock: true },
    { id: 2, name: "Cable", inStock: false },
    { id: 3, name: "Hub", inStock: true },
  ];
  const available = products.filter((p) => p.inStock);

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

Common mistakes

  • Forgetting return when using curly braces.
  • Calling map on something that is not an array (undefined before data loads). Default to [] or check first.
  • Mutating in the callback (items.sort() sorts the original). Copy first: [...items].sort().
  • Missing keys, which React reports in the console.

Key points

  • map turns an array of data into an array of elements.
  • With arrow functions: parentheses return implicitly; curly braces need return.
  • Filter and sort first (on a copy), then map.