Lists & Keys
Rendering lists is one of the most common tasks in React. The key prop is critical — it tells React which items changed, were added, or removed, enabling efficient DOM updates.
1 Rendering Lists with .map()
React — List Rendering
const products = [
{ id: 1, name: "Laptop", price: 999, inStock: true },
{ id: 2, name: "Phone", price: 699, inStock: false },
{ id: 3, name: "Monitor", price: 349, inStock: true },
];
function ProductList() {
return (
<ul className="product-list">
{products.map(product => (
<li key={product.id} className="product-item">
<span>{product.name}</span>
<span>${product.price}</span>
{product.inStock
? <span className="badge-green">In Stock</span>
: <span className="badge-red">Out of Stock</span>
}
</li>
))}
</ul>
);
}
2 Keys — Rules & Pitfalls
React — Key Rules
// ✅ Use a unique, stable ID from your data
items.map(item => <Item key={item.id} />)
// ❌ Never use array index as key (causes bugs on reorder/delete)
items.map((item, index) => <Item key={index} />)
// ✅ Keys must be unique among siblings only (not globally)
// ✅ Keys should not change between renders
// Nested lists — each level gets its own keys
categories.map(cat => (
<div key={cat.id}>
<h3>{cat.name}</h3>
{cat.items.map(item => (
<span key={item.id}>{item.name}</span>
))}
</div>
))
3 Filtering & Sorting Lists
React — Filter & Sort
function FilteredList({ items }) {
const [query, setQuery] = useState("");
const [sortBy, setSortBy] = useState("name");
const visible = items
.filter(item => item.name.toLowerCase().includes(query.toLowerCase()))
.sort((a, b) => a[sortBy] > b[sortBy] ? 1 : -1);
return (
<>
<input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search..." />
<select value={sortBy} onChange={e => setSortBy(e.target.value)}>
<option value="name">Name</option>
<option value="price">Price</option>
</select>
<ul>{visible.map(item => <li key={item.id}>{item.name}</li>)}</ul>
</>
);
}
4 Code Challenge
Challenge: Build a filterable todo list. Render todos from an array in state. Add filter tabs: "All", "Active", "Completed". Clicking a tab filters the visible todos.