Paramclasses Academy - Blog

Tutorials Details

←
Post 11 of 29
→

What is Rendering Lists in React — Using map(), Keys, and Dynamic Data ?

What is Rendering Lists in React — Using map(), Keys, and Dynamic Data ?

October 29, 2026

1. Introduction

Rendering Lists is an essential concept in React.js that allows developers to display multiple items dynamically from arrays or other data collections.

In real-world applications, data is rarely displayed as a single item. An e-commerce website displays multiple products, a dashboard displays multiple users, and a task management application displays a list of tasks.

Instead of writing separate JSX elements for every item, React developers commonly use JavaScript's map() method to transform array data into JSX elements.

For example, a product array containing five products can be rendered into five product cards using a single reusable pattern.

React also uses the special key prop to identify list items between renders. Correct keys help React determine which items were added, removed, or reordered.

By the end of this tutorial, you will understand how to render arrays, display objects, use keys correctly, and build dynamic lists for real-world React applications.

2. Learning Objectives

After completing this tutorial, you will be able to:

  1. Understand list rendering in React.

  2. Use JavaScript's map() method to render arrays.

  3. Render arrays of strings, numbers, and objects.

  4. Understand why React requires keys for list items.

  5. Use unique and stable IDs as keys.

  6. Render reusable product and user cards.

  7. Display empty states when arrays contain no items.

  8. Avoid common list-rendering errors.

  9. Build a dynamic list using React state.

3. Core Concepts and Explanation

3.1 What Is List Rendering?

List rendering means displaying multiple data items as UI elements.

Consider this JavaScript array:

const fruits = ["Apple", "Banana", "Mango"];

You could manually write three headings in JSX, but this approach becomes inefficient when the number of items changes.

Instead, React allows you to generate elements from the array using map().

3.2 Understanding the map() Method

The map() method creates a new array by calling a callback function for every element in the original array.

Syntax:

array.map((item, index) => {
  return transformedItem;
});

Example:

const numbers = [10, 20, 30];

const doubledNumbers = numbers.map((number) => {
  return number * 2;
});

console.log(doubledNumbers);

Output:

[20, 40, 60]

The original array remains unchanged. The map() method creates a new array containing the transformed values.

In React, the transformed values can be JSX elements.

3.3 Rendering an Array of Strings

function FruitList() {
  const fruits = ["Apple", "Banana", "Mango", "Orange"];

  return (
    <div>
      <h2>Fruit List</h2>

      <ul>
        {fruits.map((fruit) => (
          <li key={fruit}>{fruit}</li>
        ))}
      </ul>
    </div>
  );
}

export default FruitList;

Explanation:

  • fruits contains four strings.

  • map() processes each fruit.

  • Every fruit becomes an <li> element.

  • key={fruit} gives each item a stable key because these fruit names are unique in this example.

  • React renders the generated list inside <ul>.

Expected output:

  • Apple

  • Banana

  • Mango

  • Orange

If the array contains duplicate values, using the fruit name as the key would not be appropriate. Use unique IDs for data that can contain duplicates.

3.4 Rendering an Array of Numbers

function NumberList() {
  const numbers = [10, 20, 30, 40, 50];

  return (
    <div>
      <h2>Numbers</h2>

      {numbers.map((number) => (
        <p key={number}>Number: {number}</p>
      ))}
    </div>
  );
}

export default NumberList;

Here, every number becomes a paragraph. Using each number as a key is suitable for this example because all the values are unique.

3.5 Rendering an Array of Objects

Real applications usually render objects containing several properties rather than simple strings.

Consider this product data:

const products = [
  { id: 1, name: "Laptop", price: 55000 },
  { id: 2, name: "Smartphone", price: 25000 },
  { id: 3, name: "Headphones", price: 2000 }
];

Each object contains an ID, name, and price.

React example:

function ProductList() {
  const products = [
    { id: 1, name: "Laptop", price: 55000 },
    { id: 2, name: "Smartphone", price: 25000 },
    { id: 3, name: "Headphones", price: 2000 }
  ];

  return (
    <div>
      <h2>Our Products</h2>

      {products.map((product) => (
        <div key={product.id}>
          <h3>{product.name}</h3>
          <p>Price: ₹{product.price}</p>
        </div>
      ))}
    </div>
  );
}

export default ProductList;

Explanation:

  • product represents the current object.

  • product.id supplies the key.

  • product.name displays the product name.

  • product.price displays its price.

  • React generates one product section for each object.

This pattern is widely used in product catalogs, shopping carts, user directories, and admin dashboards.

3.6 Understanding the key Prop

A key is a special React attribute used to identify elements in a rendered list.

Example:

{products.map((product) => (
  <div key={product.id}>
    {product.name}
  </div>
))}

Here, each product has a unique ID, so React can distinguish one product from another.

Why are keys important?

Keys help React match list items between renders. When an item is inserted, removed, or reordered, stable keys help React identify which items correspond to which previous elements.

A good key should be:

  • Unique among sibling elements.

  • Stable across renders.

  • Associated with the underlying data item.

Important: The key prop is used by React and is not passed to the child component as an ordinary prop. If a child needs the ID, pass it separately.

<ProductCard
  key={product.id}
  id={product.id}
  name={product.name}
/>

3.7 Why Array Index Is Often a Poor Key

You may see this pattern:

{products.map((product, index) => (
  <div key={index}>
    {product.name}
  </div>
))}

Although an index can be acceptable for a static list that never changes order and never inserts or removes items, it is often unsuitable for dynamic lists.

When items are reordered or deleted, an index may identify a different item than before. This can cause incorrect UI associations, especially when list items contain inputs or local component state.

Prefer:

{products.map((product) => (
  <div key={product.id}>
    {product.name}
  </div>
))}

Avoid generating a random key on every render, because that causes React to treat existing items as new elements.

3.8 Rendering Lists Using a Reusable Component

For larger applications, each item can be extracted into a separate component.

function ProductCard({ product }) {
  return (
    <article>
      <h3>{product.name}</h3>
      <p>Price: ₹{product.price}</p>
    </article>
  );
}

function ProductList() {
  const products = [
    { id: 1, name: "Laptop", price: 55000 },
    { id: 2, name: "Smartphone", price: 25000 },
    { id: 3, name: "Headphones", price: 2000 }
  ];

  return (
    <section>
      <h2>Product Catalog</h2>

      {products.map((product) => (
        <ProductCard key={product.id} product={product} />
      ))}
    </section>
  );
}

export default ProductList;

Benefits:

  • Better code organization.

  • Easier maintenance.

  • Reusable UI components.

  • Simpler styling and testing.

  • Clear separation between data and presentation.

The parent list supplies the key, while ProductCard receives the product object through props.

3.9 Handling Empty Lists

Sometimes an API or database returns an empty array. A user-friendly interface should explain that no items are available.

function TaskList() {
  const tasks = [];

  return (
    <div>
      <h2>My Tasks</h2>

      {tasks.length > 0 ? (
        <ul>
          {tasks.map((task) => (
            <li key={task.id}>{task.title}</li>
          ))}
        </ul>
      ) : (
        <p>No tasks available.</p>
      )}
    </div>
  );
}

export default TaskList;

The ternary operator displays the list when tasks exist and an empty-state message otherwise.

4. Practical Code Examples

Example 1: Dynamic Student List

function StudentList() {
  const students = [
    { id: 101, name: "Aman", course: "React.js" },
    { id: 102, name: "Priya", course: "JavaScript" },
    { id: 103, name: "Rahul", course: "PHP" }
  ];

  return (
    <div>
      <h2>Student Directory</h2>

      {students.map((student) => (
        <div key={student.id}>
          <h3>{student.name}</h3>
          <p>Course: {student.course}</p>
        </div>
      ))}
    </div>
  );
}

export default StudentList;

Concept covered: Rendering multiple objects using map() and unique IDs.

Example 2: Product Catalog with Filtering

import { useState } from "react";

function ProductCatalog() {
  const [showAffordableOnly, setShowAffordableOnly] = useState(false);

  const products = [
    { id: 1, name: "Laptop", price: 55000 },
    { id: 2, name: "Mouse", price: 500 },
    { id: 3, name: "Keyboard", price: 1500 },
    { id: 4, name: "Monitor", price: 12000 }
  ];

  const visibleProducts = showAffordableOnly
    ? products.filter((product) => product.price <= 2000)
    : products;

  return (
    <div>
      <h2>Product Catalog</h2>

      <button
        onClick={() => setShowAffordableOnly(!showAffordableOnly)}
      >
        {showAffordableOnly ? "Show All Products" : "Show Affordable Products"}
      </button>

      {visibleProducts.length > 0 ? (
        visibleProducts.map((product) => (
          <div key={product.id}>
            <h3>{product.name}</h3>
            <p>Price: ₹{product.price}</p>
          </div>
        ))
      ) : (
        <p>No products found.</p>
      )}
    </div>
  );
}

export default ProductCatalog;

What happens?

  1. The original product array contains four products.

  2. When the filter is enabled, filter() selects products priced at ₹2,000 or less.

  3. map() converts the selected products into JSX.

  4. React updates the UI when the state changes.

Notice that filter() selects the items, while map() transforms those items into rendered elements.

Example 3: Adding Items to a Dynamic List

import { useState } from "react";

function TaskManager() {
  const [tasks, setTasks] = useState([
    { id: 1, title: "Learn JSX" },
    { id: 2, title: "Practice Props" }
  ]);

  const [newTask, setNewTask] = useState("");

  function addTask(event) {
    event.preventDefault();

    const title = newTask.trim();

    if (title === "") {
      return;
    }

    const task = {
      id: crypto.randomUUID(),
      title
    };

    setTasks((currentTasks) => [...currentTasks, task]);
    setNewTask("");
  }

  return (
    <div>
      <h2>Task Manager</h2>

      <form onSubmit={addTask}>
        <input
          value={newTask}
          onChange={(event) => setNewTask(event.target.value)}
          placeholder="Enter a task"
        />

        <button type="submit">Add Task</button>
      </form>

      {tasks.length > 0 ? (
        <ul>
          {tasks.map((task) => (
            <li key={task.id}>{task.title}</li>
          ))}
        </ul>
      ) : (
        <p>No tasks available.</p>
      )}
    </div>
  );
}

export default TaskManager;

What you learn:

  • useState stores the list and input value.

  • trim() prevents blank or whitespace-only tasks.

  • crypto.randomUUID() generates a unique ID in modern browsers.

  • The functional state updater uses the latest task array.

  • The spread operator creates a new array instead of mutating the existing state.

  • map() renders the updated list using stable keys.

This example is suitable for practice in a modern browser environment.

Example 4: Rendering a List of Categories

function CategoryList() {
  const categories = [
    { id: "electronics", name: "Electronics" },
    { id: "accessories", name: "Accessories" },
    { id: "computers", name: "Computers" }
  ];

  return (
    <div>
      <h2>Shop by Category</h2>

      <div>
        {categories.map((category) => (
          <button key={category.id} type="button">
            {category.name}
          </button>
        ))}
      </div>
    </div>
  );
}

export default CategoryList;

This pattern can be used to create category navigation, filter buttons, and menu items. The buttons in this example display categories but do not yet perform filtering.

5. Real-World Applications

List rendering is used in almost every data-driven React application.

E-commerce platforms

  • Product catalogs.

  • Shopping cart items.

  • Product categories.

  • Search results.

  • Customer reviews.

Admin dashboards

  • User tables.

  • Orders and transactions.

  • Inventory records.

  • Reports and activity logs.

Educational platforms

  • Student directories.

  • Course lists.

  • Lesson modules.

  • Assignment submissions.

Social applications

  • Posts and comments.

  • Followers and following lists.

  • Notifications.

  • Messages.

Task management applications

  • Todo lists.

  • Project tasks.

  • Team members.

  • Completed and pending tasks.

A typical production workflow is to obtain data from an API, handle loading and error states, and then use map() to render the resulting array.

6. Common Mistakes and Best Practices

Mistake 1: Forgetting the key

Incorrect:

{products.map((product) => (
  <p>{product.name}</p>
))}

Correct:

{products.map((product) => (
  <p key={product.id}>{product.name}</p>
))}

Mistake 2: Using duplicate keys

If two sibling elements have the same key, React cannot reliably distinguish those list items. Ensure each item has a unique key within its sibling list.

Mistake 3: Mutating the original array

Avoid changing React state arrays directly with operations such as push().

Instead, create a new array:

setItems((currentItems) => [...currentItems, newItem]);

Mistake 4: Confusing filter() and map()

  • filter() selects items that satisfy a condition.

  • map() transforms each item into a new value, such as JSX.

You can combine them when appropriate:

{products
  .filter((product) => product.price < 10000)
  .map((product) => (
    <p key={product.id}>{product.name}</p>
  ))}

Mistake 5: Forgetting empty-state handling

An empty array does not produce list items. Display a meaningful message when no records are available.

Mistake 6: Expecting key to be a regular prop

React uses key internally. Pass an item's ID separately if the child component needs it.

Best Practices

  • Prefer stable database IDs or unique data identifiers as keys.

  • Use map() to transform arrays into JSX.

  • Extract repeated item markup into reusable components.

  • Keep rendering logic readable.

  • Use filter() for selecting data and map() for rendering it.

  • Avoid mutating arrays held in React state.

  • Handle empty, loading, and error states where appropriate.

  • Test how the list behaves when items are inserted, deleted, or reordered.

7. Practice Exercises

Try solving the following exercises without copying the examples.

Exercise 1: Fruit List

Create an array of five fruits and display them using map() inside an unordered list.

Exercise 2: Employee Directory

Create an array of employee objects with id, name, and department. Render each employee's information and use a unique key.

Exercise 3: Product Catalog

Create a list of at least five products. Display each product's name and price using a reusable ProductCard component.

Exercise 4: Affordable Products

Use filter() to display only products priced below ₹5,000, then use map() to render them.

Exercise 5: Empty List

Display “No courses available” when the courses array is empty. Otherwise, render the course list.

Exercise 6: Dynamic Task Manager

Create an input field and an Add Task button. Allow users to add tasks dynamically and display the updated list.

Exercise 7: Key Behavior

Render a list of objects with unique IDs. Add and remove items, and observe why stable IDs are better than array indexes.

8. Key Takeaways and Conclusion

In this tutorial, you learned how to render dynamic lists in React using JavaScript's map() method.

Remember these essential concepts:

  1. map() transforms each array item into a new value, commonly a JSX element.

  2. Arrays of strings, numbers, and objects can all be rendered in React.

  3. Each item in a rendered list should have an appropriate, unique key among its siblings.

  4. Stable IDs are generally better than array indexes for dynamic lists.

  5. filter() selects items, while map() renders them.

  6. React state arrays should be updated immutably.

  7. Empty-state handling improves the user experience.

  8. Reusable components make large lists easier to maintain.

Understanding list rendering is an important step toward building dynamic product catalogs, dashboards, task managers, and other professional React applications.

←
Post 11 of 29
→