DEV Community

Nadeem Khan
Nadeem Khan

Posted on • Edited on

How KEY plays a vital role in React ?

In this blog, we will cover:

  • Why is a Key Needed in React?
  • Why Avoid Using the Index as a Key?
  • How Using Index as Key Creates Problems?

Consider this example where we have a list of product categories like Beauty, Fragrances, Furniture, etc. When a category is selected, we display the product details of that category using data from the dummyjson.

React:Category List Example

Code:

// src/app/page.tsx

import CategoryContainer from "@/components/home-container";
import "../styles/global.css";

export default async function Home() {
  const response = await fetch("https://dummyjson.com/products/category-list");
  const data: string[] = await response.json();
  return (
    <>
      <CategoryContainer data={data} />
    </>
  );
}

Enter fullscreen mode Exit fullscreen mode
// CategoryContainer.tsx

"use client";

import Image from "next/image";
import React, { FC, useEffect, useState } from "react";
import ProductResponse from "./from-type-folder-lets-assume";

type Props = {
  data: string[];
};


const CategoryContainer: FC<Props> = ({ data }) => {
  const [selectedCategory, setSelectedCategory] = useState("");
  const [productDetails, setProductDetails] = useState<ProductResponse | null>(
    null
  );

  useEffect(() => {
    (async () => {
      const response = await fetch(
        "https://dummyjson.com/products/category/" + selectedCategory
      );
      const data: ProductResponse = await response.json();
      setProductDetails(data);
    })();
  }, [selectedCategory]);

  return (
    <div className="max-w-6xl mx-auto my-10">
      {data?.map((item, index) => {
        return (
          <button
            key={index}
            type="button"
            onClick={() => setSelectedCategory(item)}
            className={`text-gray-900 border border-gray-300 font-medium rounded-full text-sm px-5 py-2.5 me-2 mb-2 uppercase ${
              item === selectedCategory ? "bg-gray-600 text-white" : "bg-white"
            }`}
          >
            {item}
          </button>
        );
      })}
      <h1 className="my-5 italic">
        {selectedCategory ? (
          <>
            Product Details of{" "}
            <span className="font-bold uppercase">{selectedCategory}</span>
          </>
        ) : (
          "Please select a category from above"
        )}
      </h1>

      <div className="grid grid-cols-3 gap-3">
        {productDetails?.products?.map((product, index) => {
          return (
            <div
              key={index}
              className="max-w-sm p-6 bg-white border border-gray-200 rounded-lg shadow dark:bg-gray-800 dark:border-gray-700"
            >
              <div>
                <h2>{product.title}</h2>
                <p>{product.description}</p>
                <Image
                  key={index}
                  width={100}
                  height={100}
                  className="w-full h-full"
                  src={product.images?.[0]}
                  alt={product.title}
                />
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

export default CategoryContainer;
Enter fullscreen mode Exit fullscreen mode

In the CategoryContainer, we loop through two lists: one for categories and another for product details of the selected category. Initially, we used the index as the key for both loops. This caused issues where images were not updating correctly when switching categories, as shown in this visual

React: Image Issue due to key

Debugging the Problem
When switching categories, the content updated immediately, but the images took some time to load. This suggested that React wasn't re-rendering the components correctly.

By examining the code, we noticed that using the index as the key prevented React from recognizing that new components needed to be rendered. React was reusing components with old images, leading to the delay

Solution
We needed to provide a unique key for each product. Fortunately, the API response included a unique id for each product:

React: Solution Here

Using product.id as the key resolved the issue, ensuring React correctly identified and rendered new components:

Conclusion
In React, always use a unique identifier for keys instead of the index. This ensures efficient and correct re-rendering of components, preventing issues like delayed image updates or incorrect component states.

Top comments (0)