[英]Each child in a list should have a unique "key" prop. React js
so i try to render an array of object into react js component like below:所以我尝试将 object 的数组渲染到 react js 组件中,如下所示:
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即使在我把 key={index} 放在
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?有人可以告诉我我在哪里做错了吗,在我输入 key={item} 之后应该没问题,但为什么我仍然在控制台上出错?
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您需要将密钥添加到代码中 map 内的第一个元素第一个元素是一个片段
<></>
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还要避免使用索引,它会触发警告,最好使用唯一标识符
A more proper way to handle this issue is to use a React.Fragment
element.处理这个问题的更合适的方法是使用
React.Fragment
元素。 this way you do not pollute your DOM tree with unnecessary wrapper elements.这样你就不会用不必要的包装元素污染你的 DOM 树。 Also in the accepted answer, the DOM tree is adding a
div
in between a ul
and li
set.同样在接受的答案中,DOM 树在
ul
和li
集之间添加了一个div
。 Which is invalid HTML semantics and you'll undoubtedly see errors in the console for this.这是无效的 HTML 语义,你无疑会在控制台中看到错误。
...
<ul className="pt-8">
{menuItems.map(({ icon: Icon, iconArrow: IconArrow, ...menu }) => (
<React.Fragment key={menu.id}>
...
</React.Fragment>
))}
</ul>
...
One way React optimizes + determines when a component / element needs a new render is with a key
. React 优化+确定组件/元素何时需要新渲染的一种方式是使用
key
。 You can specify it on any element to give extra control.您可以在任何元素上指定它以提供额外的控制。 However, when you are dynamically rendering elements via some form of a loop (ie mapping over an array and returning jsx), React needs some extra help knowing how to track the items
key
.但是,当您通过某种形式的循环动态呈现元素时(即映射到数组并返回 jsx),React 需要一些额外的帮助来了解如何跟踪项
key
。 This item needs to be the top most element.此项目需要是最顶层的元素。 So this is why it needs to be on the
Fragment
.所以这就是为什么它需要在
Fragment
上。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.