fefe
fefe

Reputation: 9055

React Each child in a list should have a unique "key" prop. even if the key is present

I have the following react component where I set the keys on render with uuid but still getting the warning index.js:1 Warning: Each child in a list should have a unique "key" prop.

import React, { useEffect, useState } from "react";
import { v4 as uuidv4 } from "uuid";

const Breadcrumbs = (props) => {
  const { path, lang } = props;
  const [breadcrumbsItems, setBreadcrumbsItems] = useState(null);

  useEffect(() => {
    if (path) {
      const content = path.map((item, index) => {
        if (!item.text) return null;
        const isLast = index + 1 === path.length ? true : false;
        return (
          <>
            {isLast ? (
              <span key={uuidv4()} className={"post post-jobs current-item"}>
                {item.text}
              </span>
            ) : (
              <span key={uuidv4()} property="itemListElement" typeof="ListItem">
                <a
                  property="item"
                  typeof="WebPage"
                  title={item.title}
                  href="/"
                  className="home"
                >
                  <span property="name">{item.text}</span>
                </a>
              </span>
            )}
          </>
        );
      });

      setBreadcrumbsItems(content);
    }
  }, [path]);

  return (
    <div key={uuidv4()}>
      {breadcrumbsItems ? (
        <div className="breadcrumbs uk-visible@m">
          {breadcrumbsItems && breadcrumbsItems}
        </div>
      ) : null}
    </div>
  );
};

export default Breadcrumbs;

What is wrong in this case with my code?

Upvotes: 0

Views: 826

Answers (1)

shai_sharakanski
shai_sharakanski

Reputation: 417

I think this is because the main child is your Fragment (<>).

You have to provide the key property to the main element you return from your map function.

Try to change your return to something like this:

<Fragment key={uuidv4()}>
  {isLast ? (
    <span className={"post post-jobs current-item"}>
      {item.text}
    </span>
  ) : (
    <span property="itemListElement" typeof="ListItem">
      <a
        property="item"
        typeof="WebPage"
        title={item.title}
        href="/"
        className="home"
      >
        <span property="name">{item.text}</span>
      </a>
    </span>
  )}
</Fragment>

And do not forget to import Fragment from react:

import { Fragment } from 'react';

Upvotes: 1

Related Questions