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
Define your data
Create an array of objects with your data:const itemsInCart: ItemInCart[] = [
{ productName: 'Nintendo swtich2xdd', quantity: 10 },
{ productName: 'exbos', quantity: 0 },
];
Use map() in JSX
Wrap the map function in curly braces inside your JSX:{itemsInCart.map(({ productName, quantity }) => (
// Return a component for each item
))}
Return a component
For each item in the array, return a component:<ItemCounter
name={productName}
quantity={quantity}
/>
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
Always provide keys
Never render a list without keys. React will show a warning.{items.map(item => (
<Component key={item.id} {...item} />
))}
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} />
))}
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)}
</>
);
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}
/>
))
}
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>.