Skip to main content
Rendering lists is a common pattern in React. Use the map() function to transform arrays of data into arrays of components.

Basic List Rendering

Here’s a complete example of rendering a shopping cart list:
import { ItemCounter } from "./shopping-cart/ItemCounter";

interface ItemInCart {
  productName: string;
  quantity: number;
}

const itemsInCart: ItemInCart[] = [
  { productName: 'Nintendo swtich2xdd', quantity: 10 },
  { productName: 'exbos', quantity: 0 },
  { productName: 'diyin light 3 :000', quantity: 2 },
];

export function FirstSteps() {
  return (
    <>
      <h1>Carrito de compras</h1>

      {itemsInCart.map(({ productName, quantity }) => (
        <ItemCounter 
          key={productName} 
          name={productName} 
          quantity={quantity}
        />
      ))}
    </>
  );
}

How map() Works

1

Define your data

Create an array of objects with your data:
const itemsInCart: ItemInCart[] = [
  { productName: 'Nintendo swtich2xdd', quantity: 10 },
  { productName: 'exbos', quantity: 0 },
];
2

Use map() in JSX

Wrap the map function in curly braces inside your JSX:
{itemsInCart.map(({ productName, quantity }) => (
  // Return a component for each item
))}
3

Return a component

For each item in the array, return a component:
<ItemCounter 
  name={productName} 
  quantity={quantity}
/>
4

Add a key

Always add a unique key prop to help React identify items:
<ItemCounter 
  key={productName}
  name={productName} 
  quantity={quantity}
/>

The Importance of Keys

Keys help React identify which items have changed, been added, or been removed:
{itemsInCart.map(({ productName, quantity }) => (
  <ItemCounter 
    key={productName}     // Unique identifier
    name={productName} 
    quantity={quantity}
  />
))}
Keys must be unique among siblings. Use a unique property from your data (like an ID) as the key.

Destructuring in map()

You can destructure the object directly in the map function:
// With destructuring ✅
{itemsInCart.map(({ productName, quantity }) => (
  <ItemCounter 
    key={productName}
    name={productName} 
    quantity={quantity}
  />
))}

// Without destructuring
{itemsInCart.map((item) => (
  <ItemCounter 
    key={item.productName}
    name={item.productName} 
    quantity={item.quantity}
  />
))}
Destructuring makes your code cleaner and more readable. It’s a common React pattern.

Alternative: Manual Components

Instead of using map(), you could manually create components (not recommended):
{/* Not recommended - hard to maintain */}
<ItemCounter name="Nintendo xdnt" quantity={2}/>
<ItemCounter name="exbox" quantity={0}/>
<ItemCounter name="nuse xddddd equisde" quantity={10}/>
This approach:
  • Doesn’t scale well with more items
  • Requires code changes to add/remove items
  • Can’t work with dynamic data
Always prefer map() for lists. It’s more flexible and works with dynamic data.

Defining Data Interfaces

Create interfaces for your list data:
interface ItemInCart {
  productName: string;
  quantity: number;
}

const itemsInCart: ItemInCart[] = [
  { productName: 'Nintendo swtich2xdd', quantity: 10 },
  { productName: 'exbos', quantity: 0 },
];
TypeScript will catch errors if your data doesn’t match the interface structure.

Best Practices

1

Always provide keys

Never render a list without keys. React will show a warning.
{items.map(item => (
  <Component key={item.id} {...item} />
))}
2

Use stable keys

Don’t use array index as key unless the list never reorders:
// ❌ Avoid
{items.map((item, index) => (
  <Component key={index} {...item} />
))}

// ✅ Prefer
{items.map(item => (
  <Component key={item.id} {...item} />
))}
3

Keep map callbacks simple

If the map callback gets complex, extract it to a function:
const renderItem = ({ productName, quantity }) => (
  <ItemCounter 
    key={productName}
    name={productName}
    quantity={quantity}
  />
);

return (
  <>
    {itemsInCart.map(renderItem)}
  </>
);
4

Handle empty lists

Show a message when the list is empty:
{itemsInCart.length === 0 ? (
  <p>No items in cart</p>
) : (
  itemsInCart.map(item => (...))
)}

Common Patterns

Filtering Lists

Combine filter() with map() to show only certain items:
{itemsInCart
  .filter(item => item.quantity > 0)
  .map(({ productName, quantity }) => (
    <ItemCounter 
      key={productName}
      name={productName}
      quantity={quantity}
    />
  ))
}

Transforming Data

Transform data before rendering:
{itemsInCart.map(({ productName, quantity }) => (
  <ItemCounter 
    key={productName}
    name={productName.toUpperCase()}  // Transform
    quantity={quantity}
  />
))}

Nested Lists

Render lists within lists:
{categories.map(category => (
  <div key={category.id}>
    <h2>{category.name}</h2>
    {category.items.map(item => (
      <ItemCounter key={item.id} {...item} />
    ))}
  </div>
))}

Wrapping Lists

Use fragments (<>) to avoid extra DOM elements:
export function FirstSteps() {
  return (
    <>  {/* Fragment - no extra div */}
      <h1>Carrito de compras</h1>

      {itemsInCart.map(({ productName, quantity }) => (
        <ItemCounter 
          key={productName}
          name={productName}
          quantity={quantity}
        />
      ))}
    </>
  );
}
Fragments let you group elements without adding extra nodes to the DOM. Use <> or <React.Fragment>.

Build docs developers (and LLMs) love