Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 73

Rendering Product Grids with Map

Recommended resources

Hello! Welcome back to our e-commerce project.

In our last lesson, you did a great job creating a reusable ProductCard component and learned how to pass data to it using props. This was a crucial step in making our code modular and maintainable.

Today, we'll put that new component to work. Our goal is to map over the fetched product data and render a grid of ProductCard components on our ProductsPage. This lesson will bring our product catalog to life and give you more hands-on practice with the map() array method, a key tool in modern JavaScript and a specific area you wanted to master.

From Data to Components: The Role of map()

In React, when you have an array of data (like our list of products) and you want to display each item, the standard approach is to transform that data array into an array of React components. The Array.prototype.map() method is perfect for this.

You've seen map() before in our first module. It creates a new array by calling a function on every element of the original array. In React, we use it to turn each data object into a JSX element. For example:

data.map(item => <MyComponent data={item} />)

This expression evaluates to [<MyComponent />, <MyComponent />, ...], which React knows how to render as a list of elements.

The following video provides an excellent explanation of this process. It starts by showing how you might use a traditional for loop (a more imperative style) and then refactors it to use the more concise and declarative map() method.

Rendering a List of Components in React

Watch this video from Sam Meech-Ward to see how to transform an array of data into a list of components. Pay close attention to the transition from a for loop to the map() method, as it highlights why map() is the preferred approach in React.

Watch from the beginning to the end (00:00 - 08:06). The video first demonstrates an imperative approach with a for loop (which helps build foundational understanding) and then introduces the more idiomatic .map() method. It also introduces the critical key prop, which we'll discuss next.


The "key" Prop: Giving Components a Stable Identity

As you saw in the video, whenever you render a list of elements using map(), React requires you to add a special prop called key.

Why is this necessary?

React uses the key to identify which items in a list have changed, been added, or been removed. By giving each element a unique and stable identity, React can perform updates much more efficiently. Instead of re-rendering the entire list when one item changes, it can pinpoint the exact element to update.

To reinforce this, please read the following short article.

React Lists - React Fundamentals

This W3Schools page gives a concise, clear explanation of why keys are important and what makes a good key.

Please read the section titled 'Keys in React Lists'. It will solidify your understanding of this essential concept.

The key takeaways about keys are:

  • They must be unique among sibling elements in the list.
  • They should be stable and not change between re-renders.
  • The best choice for a key is a unique ID from your data, such as product.id.
  • Using the array index as a key is generally not recommended for lists that can be reordered, filtered, or have items added/removed.

Your Turn: Building the Product Grid

It's time to apply what you've learned. Let's go back to our ProductsPage.jsx and replace our old rendering logic with our new ProductCard component.

  1. Open src/pages/ProductsPage.jsx.

  2. Import the ProductCard component at the top of the file:

    import ProductCard from '../components/ProductCard';
    
  3. Locate the return statement within your component. You should see the div that contains the loading/error messages and the product mapping logic.

  4. Modify the .map() call. Replace the div you were rendering for each product with your new ProductCard component. Pass the necessary props and, most importantly, the key.

    Your mapping logic should look like this:

    {products.map(product => (
      <ProductCard 
        key={product.id}
        title={product.title}
        price={product.price}
        image={product.image}
      />
    ))}
    

    Notice how we are passing product.id to the key prop, and the other product details as the props our ProductCard component expects.


Styling the Grid

If you run the app now, you'll see a list of product cards, but they will be stacked in a single vertical column. Let's add some simple styling to arrange them in a responsive grid.

We'll use a basic CSS Grid for this.

  1. Inside your ProductsPage component, but before the return statement, define a style object:

    const productGridStyles = {
      display: 'grid',
      // Create responsive columns: they will be at least 250px wide, 
      // but can grow to fill available space.
      gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))',
      gap: '1rem', // Adds space between the cards
      padding: '1rem'
    };
    
  2. Apply this style to the div that wraps your .map() function:

    // src/pages/ProductsPage.jsx
    
    // ... imports and component function definition ...
    
    const productGridStyles = { ... }; // The style object from above
    
    // ... loading and error handling logic ...
    
    return (
      <div style={productGridStyles}> // <-- Apply the style here
        {products.map(product => (
          <ProductCard
            key={product.id}
            title={product.title}
            price={product.price}
            image={product.image}
          />
        ))}
      </div>
    );
    

Now, when you view /products in your browser, you should see a beautiful, responsive grid of your products!


Conclusion

Great job! You have successfully integrated your reusable ProductCard component to render a dynamic list of products fetched from an API. This is a fundamental pattern you will use constantly in React development.

Key Takeaways:

  • The Array.prototype.map() method is the standard way to render lists of components from an array of data.
  • The key prop is essential for list rendering in React. It provides a stable identity for each element, allowing React to optimize performance.
  • Always use a unique and stable ID from your data (like product.id) as the key.
  • Component composition (using ProductCard inside ProductsPage) is how you build complex UIs from simple, reusable pieces.

Preview of the Next Lesson:

Our product catalog page is looking good, but it's not very interactive yet. In the next lesson, we'll build on what we've done today by implementing a search feature. You'll learn how to use state to capture user input and apply the .filter() array method to dynamically display products that match the search query.