0

I am getting the following error:

react Each child in a list should have a unique "key" prop.

Parent component:

{data.products
            .slice(4, 9)
            .map(
              ({
                onSale,
                slug,
                imageMain,
                productHeadline,
                outOfStock,
                onSalePrice,
              }) => (
                <>
                  {onSale === true ? (
                    <HomeFeatured
                      slug={slug}
                      imageMain={imageMain}
                      productHeadline={productHeadline}
                      onSalePrice={onSalePrice}
                      outOfStock={outOfStock}
                    />
                  ) : (
                    <></>
                  )}
                </>
              )
            )}
  

Child component:


function HomeFeatured({
  slug,
  imageMain,
  productHeadline,
  onSalePrice,
  outOfStock,
}) {
  return (
    <div key={slug} className="xl:w-72 lg:w-48 xs:w-60  transition ease-in-out delay-110  hover:-translate-y-1 hover:scale-105 duration-200 ">
      <div className="rounded overflow-hidden shadow-lg">
        
      </div>
    </div>
  );
}

I have added a key to the parent div but I am still getting the error in the console. I even added a key to the parent component and still would not work. I have done very similar array mapping in other parts of my application but this part has been componentised. Is this the reason why it may not be rendering possibly??

I feel like I have added the key and React is just being picky but I still would like to solve this issue.

  • Is `slug` unique in data.products? – James Oct 07 '22 at 14:46
  • slug is unique my man :) – Dan JamesEngineer Oct 07 '22 at 15:03
  • 1
    Please, take a look at this [question](https://stackoverflow.com/questions/59390955/can-i-add-a-key-prop-to-a-react-fragment) and try what is described there. `<>` needs to have a `key` due to it is top level node, returned from `.map`. And due to it cant have it - it needs to be replaced with ` ... `. – Sergey Sosunov Oct 07 '22 at 15:04

4 Answers4

2

In react you can simplify the one-line ternary statement likewise:

{onSale && (
  <HomeFeatured
    slug={slug}
    key={slug}
    imageMain={imageMain}
    productHeadline={productHeadline}
    onSalePrice={onSalePrice}
    outOfStock={outOfStock}
  />
)}

This eliminates the empty <></> problem.

The map function gives unique id along with the element every time it iterates through an Array, you can use it as a key.

.map((data, idx) => (
  <HomeFeatured key={idx}/>
))
Sergey Sosunov
  • 4,124
  • 2
  • 11
  • 15
1

You have to assign key value not inside the function. But where it is referenced. Like :

{data.products
        .slice(4, 9)
        .map(
          ({
            onSale,
            slug,
            imageMain,
            productHeadline,
            outOfStock,
            onSalePrice,
          }) => (
            <>
              {onSale === true ? (
                <HomeFeatured
                  key={slug}
                  slug={slug}
                  imageMain={imageMain}
                  productHeadline={productHeadline}
                  onSalePrice={onSalePrice}
                  outOfStock={outOfStock}
                />
              ) : (
                <div key={slug}></div>
              )}
            </>
          )
        )}
  • Not really correct. The `<>` should have the `key` due to it is the top level node, returned by the `map`. And due to `<>` cant have `key` - it needs to be replaced by `` which do have the `key` and acts in the same way as <>. – Sergey Sosunov Oct 07 '22 at 15:01
  • I tried adding the key to the parent component like you outlined and it doesn't work either – Dan JamesEngineer Oct 07 '22 at 15:02
1

You Should add the key in the parent component. React needs the key on the element you returning in the map function. It can be a component or JSX.

{data.products
        .slice(4, 9)
        .map(
          ({
            onSale,
            slug,
            imageMain,
            productHeadline,
            outOfStock,
            onSalePrice,
          }) => (
            <>
              {onSale === true ? (
                <HomeFeatured
                      slug={slug}
                      key={slug}
                      imageMain={imageMain}
                      productHeadline={productHeadline}
                      onSalePrice={onSalePrice}
                      outOfStock={outOfStock}
                    />
                  ) : (
                    <></>
                  )}
                </>
              )
            )}
  • Not really correct. The `<>` should have the `key` due to it is the top level node, returned by the `map`. And due to `<>` cant have `key` - it needs to be replaced by `` which do have the `key` and acts in the same way as <>. – Sergey Sosunov Oct 07 '22 at 15:01
0

The key property should be put on the outer most element you are mapping, it doesnt matter that in this case it's a component, it should get a key prop.

Lexus
  • 99
  • 5