Home > OS >  Each child in a list should have a unique "key" prop. React js
Each child in a list should have a unique "key" prop. React js

Time:11-24

so i try to render an array of object into react js component like below:

import React, { useState } from "react";

import { Route, Link } from "react-router-dom";

import {
  MdOutlineSpaceDashboard,
  MdOutlineStorage,
  MdOutlineFactCheck,
  MdOutlineCalculate,
  MdStickyNote2,
  MdAssignmentTurnedIn,
  MdOutlineDynamicForm,
  MdOutlineArrowDropDown,
} from "react-icons/md";
import { BsChevronDown, BsArrowLeftShort } from "react-icons/bs";

import Logo_Nabati from "../assets/logo-nabati.svg";

const menuItems = [
  { id: 1, label: "Dashboard", icon: MdOutlineSpaceDashboard, link: "/" },
  {
    id: 2,
    label: "Master Data",
    icon: MdOutlineStorage,
    iconArrow: MdOutlineArrowDropDown,
    link: "",
    subMenu: true,
    subMenuItems: [
      { id: 1, label: "KSBT", link: "/MasterData/list/KSBT" },
      { id: 2, label: "SQ01_RM", link: "/MasterData" },
      { id: 3, label: "SQ01_PM", link: "/MasterData" },
      { id: 4, label: "Depre", link: "/MasterData" },
      { id: 5, label: "OMC", link: "/MasterData" },
      { id: 6, label: "Premix", link: "/MasterData" },
      { id: 7, label: "Routing", link: "/MasterData" },
      { id: 8, label: "MP", link: "/MasterData" },
    ],
  },
  { id: 3, label: "Check COGM", icon: MdOutlineFactCheck, link: "/checkcogm" },
  {
    id: 4,
    label: "Calculation",
    icon: MdOutlineCalculate,
    link: "/calculation",
  },
  {
    id: 5,
    label: "Draft Calculation",
    icon: MdStickyNote2,
    link: "/draft",
  },
  { id: 6, label: "Approved", icon: MdAssignmentTurnedIn, link: "/approval" },
  { id: 7, label: "Task Activity", icon: MdOutlineDynamicForm, link: "/task" },
];

const Sidebar = () => {
  const [open, setOpen] = useState(false);
  const [submenuOpen, setSubmenuOpen] = useState(false);
  return (
    <div className="flex">
      <div
        className={` bg-yellow-400 h-screen p-5 pt-8  ${
          open
            ? "w-50 ease-out delay-150 peer-focus:left-0 duration-200"
            : "w-20 ease-out delay-150 peer-focus:left-0 duration-200"
        } duration-300 relative`}
      >
        <BsArrowLeftShort
          className={` bg-white text-yellow-300 text-3xl rounded-full absolute -right-3 top-9 border border-yellow-300 cursor-pointer delay-150 duration-200  ${
            !open && "rotate-180"
          }`}
          onClick={() => setOpen(!open)}
        />
        <div className={`inline-flex`}>
          <img src={Logo_Nabati} width={123} height={75} alt="logo Nabati" />
        </div>
        <ul className="pt-8">
          {menuItems.map(
            ({ icon: Icon, iconArrow: IconArrow, ...menu }, index) => (
              <>
                <Link to={menu.link}>
                  <li
                    key={index}
                    className="text-white text-sm text-justify flex items-center gap-x-4 cursor-pointer p-2 hover:bg-red-600 rounded-md mt-2"
                  >
                    <Icon className="text-2xl text-white group-hover:text-red-600" />

                    <span
                      className={`text-base font-mendium flex-1 duration-200 ${
                        !open && "hidden"
                      } `}
                    >
                      {menu.label}
                    </span>
                    {menu.subMenu && (
                      <BsChevronDown
                        className={`text-base font-mendium  duration-200 ${
                          !open && "hidden"
                        } ${submenuOpen && "rotate-180"}`}
                        onClick={() => {
                          setSubmenuOpen(!submenuOpen);
                        }}
                      />
                    )}
                  </li>{" "}
                </Link>
                {menu.subMenu && submenuOpen && open && (
                  <ul>
                    {menu.subMenuItems.map((subMenuItem, index) => (
                      <Link to={subMenuItem.link}>
                        <li
                          key={index}
                          className="text-white text-sm flex items-center gap-x-4 cursor-pointer p-1 px-12 hover:bg-red-500 rounded-md"
                        >
                          {subMenuItem.label}
                        </li>{" "}
                      </Link>
                    ))}
                  </ul>
                )}
              </>
            )
          )}
        </ul>
      </div>
    </div>
  );
};

export default Sidebar;

even after i put the key={index} on the

  • component i still got warning like this

    react-jsx-dev-runtime.development.js:119 Warning: Each child in a list should have a unique "key" prop.
    

    can someone tell me where di i do wrong here, it supposed to be no problem after i put the key={item} but why i still gettingn error on the console?

  • CodePudding user response:

    do the following

    import React, { useState } from "react";
    
    import { Route, Link } from "react-router-dom";
    
    import {
      MdOutlineSpaceDashboard,
      MdOutlineStorage,
      MdOutlineFactCheck,
      MdOutlineCalculate,
      MdStickyNote2,
      MdAssignmentTurnedIn,
      MdOutlineDynamicForm,
      MdOutlineArrowDropDown,
    } from "react-icons/md";
    import { BsChevronDown, BsArrowLeftShort } from "react-icons/bs";
    
    import Logo_Nabati from "../assets/logo-nabati.svg";
    
    const menuItems = [
      { id: 1, label: "Dashboard", icon: MdOutlineSpaceDashboard, link: "/" },
      {
        id: 2,
        label: "Master Data",
        icon: MdOutlineStorage,
        iconArrow: MdOutlineArrowDropDown,
        link: "",
        subMenu: true,
        subMenuItems: [
          { id: 1, label: "KSBT", link: "/MasterData/list/KSBT" },
          { id: 2, label: "SQ01_RM", link: "/MasterData" },
          { id: 3, label: "SQ01_PM", link: "/MasterData" },
          { id: 4, label: "Depre", link: "/MasterData" },
          { id: 5, label: "OMC", link: "/MasterData" },
          { id: 6, label: "Premix", link: "/MasterData" },
          { id: 7, label: "Routing", link: "/MasterData" },
          { id: 8, label: "MP", link: "/MasterData" },
        ],
      },
      { id: 3, label: "Check COGM", icon: MdOutlineFactCheck, link: "/checkcogm" },
      {
        id: 4,
        label: "Calculation",
        icon: MdOutlineCalculate,
        link: "/calculation",
      },
      {
        id: 5,
        label: "Draft Calculation",
        icon: MdStickyNote2,
        link: "/draft",
      },
      { id: 6, label: "Approved", icon: MdAssignmentTurnedIn, link: "/approval" },
      { id: 7, label: "Task Activity", icon: MdOutlineDynamicForm, link: "/task" },
    ];
    
    const Sidebar = () => {
      const [open, setOpen] = useState(false);
      const [submenuOpen, setSubmenuOpen] = useState(false);
      return (
        <div className="flex">
          <div
            className={` bg-yellow-400 h-screen p-5 pt-8  ${
              open
                ? "w-50 ease-out delay-150 peer-focus:left-0 duration-200"
                : "w-20 ease-out delay-150 peer-focus:left-0 duration-200"
            } duration-300 relative`}
          >
            <BsArrowLeftShort
              className={` bg-white text-yellow-300 text-3xl rounded-full absolute -right-3 top-9 border border-yellow-300 cursor-pointer delay-150 duration-200  ${
                !open && "rotate-180"
              }`}
              onClick={() => setOpen(!open)}
            />
            <div className={`inline-flex`}>
              <img src={Logo_Nabati} width={123} height={75} alt="logo Nabati" />
            </div>
            <ul className="pt-8">
              {menuItems.map(
                ({ icon: Icon, iconArrow: IconArrow, ...menu }, index) => (
                  <div key={menu.id}>
                    <Link to={menu.link}>
                      <li
                        className="text-white text-sm text-justify flex items-center gap-x-4 cursor-pointer p-2 hover:bg-red-600 rounded-md mt-2"
                      >
                        <Icon className="text-2xl text-white group-hover:text-red-600" />
    
                        <span
                          className={`text-base font-mendium flex-1 duration-200 ${
                            !open && "hidden"
                          } `}
                        >
                          {menu.label}
                        </span>
                        {menu.subMenu && (
                          <BsChevronDown
                            className={`text-base font-mendium  duration-200 ${
                              !open && "hidden"
                            } ${submenuOpen && "rotate-180"}`}
                            onClick={() => {
                              setSubmenuOpen(!submenuOpen);
                            }}
                          />
                        )}
                      </li>{" "}
                    </Link>
                    {menu.subMenu && submenuOpen && open && (
                      <ul>
                        {menu.subMenuItems.map((subMenuItem, index) => (
                          <Link to={subMenuItem.link} key={`${menu.id}-${subMenuItem.id}`}>
                            <li
                              key={index}
                              className="text-white text-sm flex items-center gap-x-4 cursor-pointer p-1 px-12 hover:bg-red-500 rounded-md"
                            >
                              {subMenuItem.label}
                            </li>{" "}
                          </Link>
                        ))}
                      </ul>
                    )}
                  </div>
                )
              )}
            </ul>
          </div>
        </div>
      );
    };
    
    export default Sidebar;
    

    you need to add the key to the first element inside the map in your code the first element is a fragment

    <></>
    

    that way is not working when you do it on the

    <li key={index}
    

    also avoid to use index it will trigger a warning and is better practice use a unique identifier

    • Related