首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >列表中的每个孩子都应该有一个独特的“键”道具。反应js

列表中的每个孩子都应该有一个独特的“键”道具。反应js
EN

Stack Overflow用户
提问于 2022-11-24 02:19:27
回答 2查看 56关注 0票数 0

因此,我尝试将一个对象数组呈现为react组件,如下所示:

代码语言:javascript
复制
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;

即使在我将key={索引}放到

  • 组件--我仍然收到这样的警告

.jsx:119警告:列表中的每个子项目都应该有一个唯一的“键”支柱。

有人能告诉我我在这里做错了什么吗?在我把key={item}放上去之后,应该没问题,但是为什么我仍然在控制台上出错呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-24 03:05:17

执行以下操作

代码语言:javascript
复制
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;

您需要在代码中将键添加到映射中的第一个元素,第一个元素是一个片段。

代码语言:javascript
复制
<></>

当您在

代码语言:javascript
复制
<li key={index}

此外,避免使用索引,它将触发警告,更好的做法是使用唯一标识符。

票数 1
EN

Stack Overflow用户

发布于 2022-11-28 20:45:44

处理此问题的一种更恰当的方法是使用React.Fragment元素。这样,您就不会用不必要的包装器元素污染DOM树。在接受的答案中,DOM树还在ulli集合之间添加了一个li。这是无效的HTML语义,您无疑会看到控制台中的错误。

代码语言:javascript
复制
...

<ul className="pt-8">
  {menuItems.map(({ icon: Icon, iconArrow: IconArrow, ...menu }) => (
    <React.Fragment key={menu.id}>
      ...
    </React.Fragment>
  ))}
</ul>
...

优化+的一种方法是使用key确定组件/元素何时需要新的呈现。您可以在任何元素上指定它来提供额外的控制。但是,当您通过某种形式的循环(即在数组上映射并返回jsx)动态呈现元素时,React需要一些额外的帮助,以了解如何跟踪项key。这个项目需要是最重要的元素。所以这就是为什么它需要在Fragment上。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74554925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档