当我有一个唯一的钥匙时,我会收到一个独特的密钥道具警告



我是新手,但我知道唯一密钥的主要概念。但是,我会得到警告。

下面我有一个项目组件:

class Item extends Component {
    state = {}
    render() { 
        return ( 
            <React.Fragment>
                {this.props.item.todo}
            </React.Fragment>
        );
    }
}

及以下是我的物品组件,我有独特的密钥:

render() { 
    const { items } = this.props;
    return ( 
        items.map(item=>
            <React.Fragment>
                <Item key={item.todo} item={item} />
            </React.Fragment>
        )    
    );
}

随着所有这些,我会得到警告!

正如其他人所说的那样,您需要将key设置在顶部元素上,在您的情况下为Fragment。但是我会更改关键值。我不知道您在item.todo中拥有哪种数据,但是仅设置item.todo值的键可能会出现问题。我会解释的。

键只能在其兄弟姐妹中

react.org文档列表和键完美地总结了这一点,因此我不会用另一种方式解释。它在下面说。

阵列中使用的键在其兄弟姐妹中应该是唯一的。但是,它们不需要在全球范围内独特。产生两个不同的数组时,我们可以使用相同的键:

(注意:它不需要是有意义的数据)。

一个密钥应稳定

这意味着在呈现密钥之间不应更改,因此请勿使用 Math.random() 人们认为使用会很好。

为什么上述重要?

在您的数据中,如果两个items.todo是相同的值,则它将破坏上述值。您的钥匙不是唯一的。这可能会导致不必要的重新订阅者的性能问题。

我建议使用具有items.todo和地图的index值的密钥。这样,如果您确实具有相同的items.todo值,则添加索引将使关键唯一。考虑到这一点,我会写你的片段。

render() { 
  const { items } = this.props;
  return ( 
    items.map((item, index) => (
      <React.Fragment key={item.todo + index}>
        <Item item={item} />
      </React.Fragment>
    ))
  );
}

这是列表和键上的react.org文档的链接,是ereact.org文档有关片段的链接。两者都提供示例和有用的信息。他们是一本很好的阅读,我强烈建议您。

我还注意到您正在使用React.Fragment,但是只需使用Component声明您的课程。您可以做我假设您为Component所做的事情,并破坏Fragement。如下:

import React, { Component, Fragment } from 'react';

因此,您的片段有点干净,如下:

items.map((item, index) => (
  <Fragment key={item.todo + index}>
    <Item item={item} />
  <Fragment>
))

您需要按照答案中建议的@tholle建议将key道具保留在顶部元素上。但是在这里,我想建议的是不使用<React.Fragment>

items.map(item=>
   <Item key={item.todo} item={item} />
)

每当您不想用<div /><p />等包装器包装元素时,都会使用Fragment。由于使用<Item />组件,使用Fragment是不必要的。

>

这是您可以使用Fragment的示例:

items.map(item=>
   <React.Fragment key={item.todo}>
     <Item item={item} />
     <p>Another Component...</p>
   </React.Fragment>
)

但是,对不起,如果您使用Fragment的别名:<></>不支持key Props。它应该明确设置,根本没有道具。如果您需要使用key

,则需要用元素包装它们
items.map(item=>
   <div key={item.todo}>
     <Item item={item} />
     <p>Another Component...</p>
   </div>
)

这将是无效的:

items.map(item=>
   <key={item.todo}>
     <Item item={item} />
     <p>Another Component...</p>
   </>
)

您需要将key Prop放在顶部元素上,即React.Fragment而不是Item

items.map(item=>
  <React.Fragment key={item.todo}>
    <Item item={item} />
  </React.Fragment>
)    

给出react.fragment

的关键
render() { 
  const { items } = this.props;
  return ( 
    items.map(item =>
      <React.Fragment key={item.todo}>
        <Item item={item} />
      </React.Fragment>
    )
  );
}

一个更好的解决方案是使用ShortID NPM软件包。它被描述为"惊人的简短不顺序的URL友好型唯一ID生成器。"

使用阵列索引作为键是反图案。在本文中了解更多信息。ESLINT还可以防止此 ->防止在键中使用数组索引(react/no-array-index-key)

这是我的使用方式。

npm install shortid

import shortid from 'shortid'
// using https://www.npmjs.com/package/shortid to prevent duplicate fragment keys
names.map(name => {
    return (
        <Fragment key={`fragment-${id}-${shortid.generate()}`}>
            Hello, {name}!
        </Fragment>
    )
});

最新更新