ReactJs:不带索引的子键道具

ReactJs:不带索引的子键道具,reactjs,Reactjs,您好,我试图在我的组件中使用索引作为键,但最终从eslint和reactjs自己的文档中得到错误,他们建议在最后一个选项中使用索引 通过研究,我发现了为每个组件生成uuid的方法,但这似乎成本很高 这是我的数组,我要用它: export const Tags: ITag[] = [ { Title: 'DashBoard', Name: 'Default', Link: '../dashboards', Icon: AiOutlineDashboard,

您好,我试图在我的组件中使用索引作为键,但最终从eslint和reactjs自己的文档中得到错误,他们建议在最后一个选项中使用索引 通过研究,我发现了为每个组件生成uuid的方法,但这似乎成本很高

这是我的数组,我要用它:

export const Tags: ITag[] = [
  {
    Title: 'DashBoard',
    Name: 'Default',
    Link: '../dashboards',
    Icon: AiOutlineDashboard,
    DropdownItems: null,
  },
  {
    Name: 'Analytic',
    Link: '../dashboards',
    Icon: AiOutlineLineChart,
    DropdownItems: null,
  },
  {
    Name: 'Inventory',
    Link: '../dashboards',
    Icon: BiStoreAlt,
    DropdownItems: null,
  },
  {
    Title: 'Pages',
    Name: 'Employees',
    Link: '../dashboards',
    Icon: TiGroupOutline,
    DropdownItems: [
      {Name: 'Employee List', Link: '/eloBost'},
      {Name: 'View Employee', Link: '/duoBoost'},
      {Name: 'New Employee', Link: '/eloBost'},
      {Name: 'Any', Link: '/duoBoost'},
    ],
  },
  {
    Name: 'Departaments',
    Link: '../dashboards',
    Icon: FaRegBuilding,
    DropdownItems: [
      {Name: 'Elo Boost', Link: '/eloBost'},
      {Name: 'Duo Boost', Link: '/duoBoost'},
      {Name: 'MD10', Link: '/eloBost'},
      {Name: 'Coaching', Link: '/duoBoost'},
      {Name: 'Vitóriais', Link: '/duoBoost'},
    ],
  },
  {
    Name: 'Products',
    Link: '../dashboards',
    Icon: BsLightning,
    DropdownItems: [
      {Name: 'Elo Boost', Link: '/eloBost'},
      {Name: 'Duo Boost', Link: '/duoBoost'},
      {Name: 'MD10', Link: '/eloBost'},
      {Name: 'Coaching', Link: '/duoBoost'},
      {Name: 'Vitóriais', Link: '/duoBoost'},
    ],
  },
  {
    Name: 'Suppliers',
    Link: '../dashboards',
    Icon: BsBookmarkPlus,
    DropdownItems: [
      {Name: 'Elo Boost', Link: '/eloBost'},
      {Name: 'Duo Boost', Link: '/duoBoost'},
      {Name: 'MD10', Link: '/eloBost'},
      {Name: 'Coaching', Link: '/duoBoost'},
      {Name: 'Vitóriais', Link: '/duoBoost'},
    ],
  },
  {
    Name: 'Contracts',
    Link: '../dashboards',
    Icon: BsFileEarmarkText,
    DropdownItems: [
      {Name: 'Elo Boost', Link: '/eloBost'},
      {Name: 'Duo Boost', Link: '/duoBoost'},
      {Name: 'MD10', Link: '/eloBost'},
      {Name: 'Coaching', Link: '/duoBoost'},
      {Name: 'Vitóriais', Link: '/duoBoost'},
    ],
  },
  {
    Name: 'User List',
    Link: '../dashboards',
    Icon: RiGroupLine,
    DropdownItems: [
      {Name: 'Elo Boost', Link: '/eloBost'},
      {Name: 'Duo Boost', Link: '/duoBoost'},
      {Name: 'MD10', Link: '/eloBost'},
      {Name: 'Coaching', Link: '/duoBoost'},
      {Name: 'Vitóriais', Link: '/duoBoost'},
    ],
  },
];
在我的jsx上,我滚动列表并执行以下操作:

{tags.map((item) => (
        <>
          {item.Title ? (
            <TitleItem key={generateKey(item.Title.toString())} open={open}>
              {item.Title}
            </TitleItem>
          ) : (
            ""
          )}
          <TagList
            open={open}
            key={generateKey(item.Name.toString())}
            sideBarStatus={open}
            tag={item}
            clickHandler={clickHandler}
          />
        </>
      ))}
ss:

带有控制台警告的codesandbox:

生成
uuid
可能比使用索引更糟糕。在大多数情况下,使用
索引
值就可以了。有一个固定的
id
用作
值是理想的,因为它消除了在移动、重新排列项目和从列表中添加/删除时重新渲染的需要,但它实际上只是一种大多数程序都不需要的优化


也就是说,如果您有一个
id
,特别是对于来自外部服务器源的数据,请使用该id。如果这是一个静态列表,只需向对象添加
id
属性。

生成
uuid
可能比使用索引更糟糕。在大多数情况下,使用
索引
值就可以了。有一个固定的
id
用作
值是理想的,因为它消除了在移动、重新排列项目和从列表中添加/删除时重新渲染的需要,但它实际上只是一种大多数程序都不需要的优化


也就是说,如果您有一个
id
,特别是对于来自外部服务器源的数据,请使用该id。如果这是一个静态列表,只需向对象添加一个
id
属性。

问题在于包装器片段的使用。这就是它抱怨没有钥匙的原因。您将看到,如果将包装片段替换为具有键的DIV,则警告将消失。下面是您的更改示例:

问题在于您对包装器片段的使用。这就是它抱怨没有钥匙的原因。您将看到,如果将包装片段替换为具有键的DIV,则警告将消失。下面是您的更改示例:

React
中,您应该使用
key
来渲染列表,以便
React
可以在渲染之间映射状态并进行最少数量的渲染。 如果未指定
,则将使用元素的
索引
。但你可能会面临警告

要解决此问题,您需要使用
id
,但在渲染之间不会更改。 您的
generateKeys
方法添加了当前日期,但这不是真的。因此,相反,会降低
React
的性能

在您的情况下,可以使用
名称
字段作为唯一键。 但请记住,最好使用
id
,因为如果有两个元素具有相同的
名称
字段,则会出现错误

而且您不需要在
映射中提供多个
仅由
根元素所需。因此,在
贴图中进行渲染的代码应如下所示:

<MenuList open={open}>
    {tags.map((item) => (
        <div key={item.Name}>
            {item.Title ? <TitleItem open={open}>{item.Title}</TitleItem> : ""}
            <TagList
                open={open}
                sideBarStatus={open}
                tag={item}
                clickHandler={clickHandler}
            />
        </div>
    ))}
</MenuList>

{tags.map((项)=>(
{item.Title?{item.Title}:“}”
))}
我对
Drop
组件做了一些修复,该组件也误用了

可以看到更正后的代码


另外,我建议您阅读有关如何使用
React
中中的键的更多详细信息。您应该使用
key
来渲染列表,以便
React
可以在渲染之间映射状态并进行最少数量的渲染。 如果未指定
,则将使用元素的
索引
。但你可能会面临警告

要解决此问题,您需要使用
id
,但在渲染之间不会更改。 您的
generateKeys
方法添加了当前日期,但这不是真的。因此,相反,会降低
React
的性能

在您的情况下,可以使用
名称
字段作为唯一键。 但请记住,最好使用
id
,因为如果有两个元素具有相同的
名称
字段,则会出现错误

而且您不需要在
映射中提供多个
仅由
根元素所需。因此,在
贴图中进行渲染的代码应如下所示:

<MenuList open={open}>
    {tags.map((item) => (
        <div key={item.Name}>
            {item.Title ? <TitleItem open={open}>{item.Title}</TitleItem> : ""}
            <TagList
                open={open}
                sideBarStatus={open}
                tag={item}
                clickHandler={clickHandler}
            />
        </div>
    ))}
</MenuList>

{tags.map((项)=>(
{item.Title?{item.Title}:“}”
))}
我对
Drop
组件做了一些修复,该组件也误用了

可以看到更正后的代码


另外,我建议您阅读更多关于如何使用标记列表中的键的详细信息,您可以使用item.toString()-该项指示灯指向[object]字符串。例如,您应该执行item.Name.toString(),如果此警告中仍有帮助,您可以帮助我完成此操作吗?检查
MenuTags
的渲染方法。有关详细信息,请参阅。您不应该在密钥中使用时间戳。这将导致不必要的重新渲染。如果您真的希望它脱离对象的字符串化版本,您可以将其字符串化
JSON.stringify(item)
。为将要更改的密钥(如时间戳或uuid)生成的任何值都将是低效的,通常不被认为是一种好的做法。键应与其呈现的数据/内容相关。这有助于重新渲染与实际渲染紧密结合data@JohnRuddell你可以看看这里:我尝试使用json stringify,但我已经有了这个错误:检查菜单项的render方法。请参阅reactjs.org/link/warning-keys以了解标记列表中的更多信息
<MenuList open={open}>
    {tags.map((item) => (
        <div key={item.Name}>
            {item.Title ? <TitleItem open={open}>{item.Title}</TitleItem> : ""}
            <TagList
                open={open}
                sideBarStatus={open}
                tag={item}
                clickHandler={clickHandler}
            />
        </div>
    ))}
</MenuList>