React

React Lists — Rendering & Manipulating Arrays

Thirdy Gayares
18 min read

🎓 What You Will Learn

  • Rendering Lists: Use .map() to display arrays as UI
  • Keys in Lists: Why unique key props matter
  • Adding Items: Use spread operator to add to arrays
  • Removing Items: Use .filter() to delete items
  • Updating Items: Modify list items with .map()
  • Filtering Lists: Search and filter data dynamically
  • Sorting Lists: Sort by different properties
  • Nested Lists: Work with complex nested data structures
1

Why Lists Matter in React

Lists are everywhere in modern apps: todo items, product catalogs, user feeds, shopping carts, etc. React makes it simple to render, update, and manage lists with built-in methods like .map(), .filter(), and .sort().

Instead of manually writing HTML for each item, you describe ONE item and React repeats it for every item in your array. This is the power of component-driven development.

2

Rendering Lists with .map()

The .map() method transforms each item in an array into JSX. This is the primary way to render lists in React.

basic-map.jsx
const items = ["Apple", "Banana", "Orange"];

// Transform each item into JSX
const listItems = items.map((item, index) => (
  <li key={index}>{item}</li>
));

// Render all items
return <ul>{listItems}</ul>;

// Or inline it:
return (
  <ul>
    {items.map((item, index) => (
      <li key={index}>{item}</li>
    ))}
  </ul>
);
1🍎 Apple
2🍌 Banana
3🍊 Orange
4🥭 Mango
5🍇 Grapes
3

Keys — The Critical Prop

Every list item needs a key prop. React uses keys to track which items have changed, been added, or removed. Without keys, bugs happen.

❌ Don't use index as key if your list can change (reorder, filter, add/remove items). Index-based keys break state.

✅ Use unique IDs from your data:

good-keys.jsx
const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 3, name: "Charlie" },
];

return (
  <ul>
    {users.map(user => (
      <li key={user.id}>{user.name}</li>  // ✅ Use unique ID
    ))}
  </ul>
);
Why keys matter: React uses keys to identify which items have changed. Without proper keys, state gets mixed up between items.
4

Adding Items to a List

To add items, use the spread operator ... to create a new array (never mutate state directly).

add-item.jsx
const [items, setItems] = useState(["Apple", "Banana"]);

const addItem = (newItem) => {
  // ✅ GOOD: Create new array with spread
  setItems([...items, newItem]);

  // ❌ BAD: Mutating directly
  // items.push(newItem);  // Don't do this!
};

// Generate unique ID
const handleAdd = () => {
  const newItem = {
    id: Date.now(),
    text: input,
    completed: false
  };
  setItems([...items, newItem]);
};
Learn React Lists
Build a Todo App

2 total • 0 completed

5

Removing Items from a List

Use .filter() to remove items. Filter creates a new array with only items that match your condition.

remove-item.jsx
const [items, setItems] = useState([...]);

const removeItem = (idToRemove) => {
  // Keep all items EXCEPT the one to remove
  setItems(items.filter(item => item.id !== idToRemove));
};

return (
  <>
    {items.map(item => (
      <div key={item.id}>
        {item.name}
        <button onClick={() => removeItem(item.id)}>
          Delete
        </button>
      </div>
    ))}
  </>
);
6

Updating Items in a List

To update an item, use .map(). Check which item to update and return a modified version.

update-item.jsx
const [items, setItems] = useState([...]);

const updateItem = (idToUpdate, newValue) => {
  setItems(
    items.map(item =>
      item.id === idToUpdate
        ? { ...item, ...newValue }  // Update this item
        : item                       // Keep others
    )
  );
};

// Usage
const handleUpdateQuantity = (id, newQty) => {
  updateItem(id, { quantity: newQty });
};
Apple
5
Banana
3
Orange
8
7

Filtering & Searching

Filter lists dynamically by storing a search term in state and using .filter().

search.jsx
export function ProductSearch() {
  const [searchTerm, setSearchTerm] = useState("");

  const products = [
    { id: 1, name: "Laptop", price: 999 },
    { id: 2, name: "Mouse", price: 29 },
    { id: 3, name: "Monitor", price: 299 },
  ];

  // Filter products matching search
  const filtered = products.filter(p =>
    p.name.toLowerCase().includes(searchTerm.toLowerCase())
  );

  return (
    <>
      <input
        value={searchTerm}
        onChange={(e) => setSearchTerm(e.target.value)}
        placeholder="Search..."
      />
      {filtered.map(product => (
        <div key={product.id}>{product.name}</div>
      ))}
    </>
  );
}

Laptop

Electronics

$999

Phone

Electronics

$599

Notebook

Stationery

$5

Pen

Stationery

$2

Monitor

Electronics

$299

Showing 5 of 5 products

8

Sorting Lists

Use .sort() to arrange items. Always create a copy first[...array].sort().

sorting.jsx
const [sortBy, setSortBy] = useState("name");

const products = [
  { id: 1, name: "Laptop", price: 999 },
  { id: 2, name: "Phone", price: 599 },
];

// Create copy, then sort
const sorted = [...products].sort((a, b) => {
  if (sortBy === "name") {
    return a.name.localeCompare(b.name);  // A-Z
  } else {
    return a.price - b.price;  // Low to high
  }
});

return (
  <>
    <button onClick={() => setSortBy("name")}>
      Sort by Name
    </button>
    {sorted.map(p => (
      <div key={p.id}>{p.name}</div>
    ))}
  </>
);
Keyboard$79
Laptop$999
Monitor$299
Phone$599
Tablet$399
9

Nested Lists

When you have lists within lists (teams with members, categories with products), use nested .map() calls.

nested.jsx
const teams = [
  { id: 1, name: "Frontend", members: ["Alice", "Bob"] },
  { id: 2, name: "Backend", members: ["Charlie"] },
];

return (
  <>
    {teams.map(team => (
      <div key={team.id}>
        <h3>{team.name}</h3>
        <ul>
          {team.members.map((member, idx) => (
            <li key={idx}>{member}</li>
          ))}
        </ul>
      </div>
    ))}
  </>
);

👥 Frontend

  • Alice
  • Bob

👥 Backend

  • Charlie
  • Diana
  • Eve

👥 DevOps

  • Frank
10

Array Methods Cheat Sheet

MethodWhat It DoesExampleUse For
<Code>.map()</Code>Transform each itemitems.map(x => ...)Render lists
<Code>.filter()</Code>Keep matching itemsitems.filter(x => ...)Search, delete
<Code>.find()</Code>Get first matchitems.find(x => ...)Find one item
<Code>.sort()</Code>Order items[...items].sort(...)Sorting
<Code>.slice()</Code>Get portionitems.slice(0, 5)Pagination
<Code>.includes()</Code>Check existenceitems.includes(x)Validation
11

Best Practices

Use unique keys: from your data (id, uuid), not index
Never mutate state: create new arrays with spread or methods
Copy before sorting: use [...array].sort()
Extract list items to components: for cleaner, reusable code
Handle empty lists: show helpful "No items" message
12

Common Mistakes

1Mistake: Wrong Key Prop
mistake-keys.jsx
// ❌ BAD: Using index as key
{items.map((item, index) => (
  <li key={index}>{item}</li>
))}

// ✅ GOOD: Using unique ID
{items.map((item) => (
  <li key={item.id}>{item.name}</li>
))}
2Mistake: Mutating State
mistake-mutate.jsx
// ❌ BAD: Mutating directly
items.push(newItem);
setItems(items);

// ✅ GOOD: Create new array
setItems([...items, newItem]);
3Mistake: Not Copying Before Sort
mistake-sort.jsx
// ❌ BAD: Original array gets sorted
items.sort((a, b) => a - b);
setItems(items);

// ✅ GOOD: Copy first, then sort
setItems([...items].sort((a, b) => a - b));
13

Real-World Example: Shopping Cart

ShoppingCart.jsx
import { useState } from 'react';

export function ShoppingCart() {
  const [items, setItems] = useState([
    { id: 1, name: "Laptop", price: 999, quantity: 1 },
    { id: 2, name: "Phone", price: 599, quantity: 2 },
  ]);

  const updateQuantity = (id, qty) => {
    setItems(items.map(item =>
      item.id === id ? { ...item, quantity: qty } : item
    ));
  };

  const removeItem = (id) => {
    setItems(items.filter(item => item.id !== id));
  };

  const total = items.reduce(
    (sum, item) => sum + (item.price * item.quantity),
    0
  );

  return (
    <>
      {items.map(item => (
        <div key={item.id}>
          <h3>{item.name}</h3>
          <p>${item.price}</p>
          <input
            type="number"
            value={item.quantity}
            onChange={(e) => updateQuantity(item.id, +e.target.value)}
          />
          <button onClick={() => removeItem(item.id)}>
            Remove
          </button>
        </div>
      ))}
      <p>Total: ${total}</p>
    </>
  );
}
14

What's Next?

🚀 Next Learning Topics:
  • React Hooks: useEffect for fetching list data from APIs
  • Performance: React.memo for list items, virtualization for large lists
  • Advanced Patterns: Extract list items to separate components
  • State Management: Redux or Context for complex list state
  • Forms & Lists: Building dynamic forms with repeating fields

Keep practicing! 💪 Lists are fundamental in React. Build more projects with different list types (todos, products, users, etc.) and you'll master this skill quickly!

About the Author

TG

Thirdy Gayares

Passionate developer creating custom solutions for everyone. I specialize in building user-friendly tools that solve real-world problems while maintaining the highest standards of security and privacy.