Lists & Keys
Rendering Lists with map()
React has no special directive like v-for or ng-repeat. Instead, use the JavaScript map() method on an array to return an array of elements.
function FruitList() {
const fruits = ["Apple", "Mango", "Orange", "Watermelon"];
return (
<ul>
{fruits.map((item) => (
<li>{item}</li>
))}
</ul>
);
}
Why Keys Matter?
key is a special attribute that helps React identify each element in a list. Without a key, React will emit a warning and rendering performance can degrade.
function FruitList() {
const fruits = ["Apple", "Mango", "Orange"];
return (
<ul>
{fruits.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
);
}
Keys must be:
- Unique among siblings
- Stable (not changing between renders)
- A string or a number
Index as a Key
An array index may be used as a key only if the list will never be sorted, filtered, or modified.
// OK to use if the list is static and never changes
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
// NOT OK — the list can change (add/remove/sort)
{items.map((item, index) => (
<li key={index}>{item.name}</li> // Avoid!
))}
Complex Lists: Arrays of Objects
Most real-world cases use arrays of objects. Use a unique ID as the key.
function ProductList() {
const products = [
{ id: 1, name: "Laptop", price: 12000000 },
{ id: 2, name: "Mouse", price: 150000 },
{ id: 3, name: "Keyboard", price: 350000 },
];
return (
<div className="product-list">
{products.map((item) => (
<div key={item.id} className="product-card">
<h3>{item.name}</h3>
<p>$ {item.price.toLocaleString("en-US")}</p>
</div>
))}
</div>
);
}
Complete Example: Filtering and Rendering
import { useState } from 'react';
function ProductList() {
const [filter, setFilter] = useState("");
const products = [
{ id: 1, name: "Laptop ASUS", category: "computer", price: 12000000 },
{ id: 2, name: "Mouse Logitech", category: "accessory", price: 150000 },
{ id: 3, name: "Keyboard Mechanical", category: "accessory", price: 350000 },
{ id: 4, name: "Monitor LG", category: "computer", price: 3500000 },
];
const filteredProducts = products.filter((item) =>
item.name.toLowerCase().includes(filter.toLowerCase())
);
return (
<div>
<input
type="text"
value={filter}
onChange={(e) => setFilter(e.target.value)}
placeholder="Search products..."
/>
<div className="grid">
{filteredProducts.map((item) => (
<div key={item.id} className="card">
<h3>{item.name}</h3>
<p>Category: {item.category}</p>
<p>$ {item.price.toLocaleString("en-US")}</p>
</div>
))}
</div>
{filteredProducts.length === 0 && (
<p>No products found.</p>
)}
</div>
);
}
export default ProductList;
Summary
Rendering lists in React uses map() with a unique key attribute. Use an ID from the data, not the index, unless the list is truly static. Combine it with conditional rendering for a better experience.
The next chapter covers Forms — how to manage form inputs with controlled and uncontrolled components.