ReactJS:在数组元素中赋予键的最佳方法是什么

时间:2018-04-15 10:50:35

标签: javascript reactjs

我刚刚开始使用ReactJS并尝试了与此类似的其他问题的解决方案,但到目前为止还没有运气。

这是我的工作代码:

import React from 'react';
import ReactDOM from 'react-dom';


const Numbers = ['2', '4', '6', '8'];

const NumbersList = (props) => (
   <ul>
      {
          props.Numbers.map (
             number => <li key={number}>{number * 2}</li>
          )
      }
    </ul>
)
ReactDOM.render(<NumbersList Numbers = {Numbers} />, document.getElementById('root') )

但是当我将Numbers Array传递给:

const Numbers = ['4', '4', '6', '8']

我收到此错误:

警告:遇到两个具有相同密钥的孩子4。密钥应该是唯一的,以便组件在更新时保持其身份。

所以我的问题是:在这种情况下给钥匙的最佳方法是什么?如果我使用Number(如上例所示)作为Keys,那么避免此警告的最佳解决方案是什么?

谢谢!

7 个答案:

答案 0 :(得分:3)

如果您没有项目的唯一属性(非唯一原语列表),则可以使用索引。

注意:如果项目具有唯一id(并且应该是非基元列表),则不要使用索引,因为它是{{ 3}}

&#13;
&#13;
const Numbers = ['2', '4', '4', '8'];

const NumbersList = (props) => (
  <ul>
  {
  props.Numbers.map (
    (number, index) => <li key={index}>{number * 2}</li>
  )}
  </ul>
)

ReactDOM.render(
  <NumbersList Numbers = {Numbers} />,
  document.getElementById('root')
)
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

原因是每个<li>标记应具有唯一键。您在key=4代码中指定<li>,因为元素4在您的数组中是重复的。

编辑后

我的坏,我没有读完整个问题。 使用uuid包生成新的id:https://www.npmjs.com/package/uuid他们也有文档。

答案 2 :(得分:1)

这样做会添加一个唯一的密钥以及自定义数据

import React from 'react';
import ReactDOM from 'react-dom';


const Numbers = ['2', '4', '6', '8'];

const NumbersList = (props) => (
   <ul>
      {
          props.Numbers.map (
             (number, i) => <li key={i} custom={number}>{number * 2}</li>
          )
      }
    </ul>
)
ReactDOM.render(<NumbersList Numbers = {Numbers} />, document.getElementById('root') )

关键道具应该是唯一的,所以我从map方法中给出了返回的值,自定义属性将是您要为所有元素设置的数组数据。

答案 3 :(得分:0)

React希望重复的项目(兄弟姐妹)拥有一个关键属性,以便它可以区分后续渲染中的项目。这允许它在项目进出,变化时优化元素图形的渲染。

key意味着是一个字符串,但是React会强制为你编号一个数字。您的示例非常简单,数据包含一些唯一的项值(例如数据库记录ID)更为正常,因此可以支持重复的属性但仍允许区分项目。如果没有外部id属性,您可以决定添加唯一标识符作为状态的一部分。

可以在列表中使用项目索引,但这并不总是允许React优化项目的渲染周期。这就是为什么如果您的数据包含唯一的项目标识符,则不鼓励它。

React检查重复和缺失的键,以避免可能导致渲染周期效率降低的最明显的错误。

Reacts渲染优化将对很长的列表产生影响。对于范围可能只是几个项目的应用程序,获得了很大的收益,因此数组索引可能是一个合理的解决方案。

答案 4 :(得分:0)

使用index作为key是一种反模式,并且在任何情况下都会导致错误。

要获得最佳答案 - 如果有人将索引1后面的数字更改为5,会发生什么?显示的数字将保持不变,因为 key 未更改

要绕过因使用index作为基元key而导致的问题,我建议使用复合键

我会用下一个方式编写NumbersList组件:

const NumbersList = ({ numbers }) => ( <ul> {numbers.map((number, index) => ( <li key={`${index}:${number}`}>{number * 2}</li> )} </ul> );

答案 5 :(得分:0)

React使用keys来标识哪些元素已更改,添加或删除。

选择key的最佳方法是使用一个字符串,该字符串唯一地标识其同级项中的列表项。通常,您会使用数据中的ID作为键。

不建议使用数组索引作为键,因为您可能会从数组中更新/删除元素,但是索引将保持不变,因此React将无法识别更改并显示错误的结果。

在您的代码中,数组元素没有唯一的ID,因此唯一可以使它唯一的就是数组索引。

const Numbers = ['2', '4', '4', '8'];

const NumbersList = (props) => (
  <ul>
  {
  props.Numbers.map (
    (number, index) => <li key={index}>{number * 2}</li>
  )}
  </ul>
)

ReactDOM.render(
  <NumbersList Numbers = {Numbers} />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

答案 6 :(得分:-1)

我最终为自己创建了这种格式,并且我在各处都认真地使用了它。

results.map((item, index) => <li key={`home_results_${index + 1}`}>{item}</li>)

这为每个循环赋予了唯一的键名称,因此只需确保尽可能简短地命名这些列表,然后将索引附加到该列表即可。

因此,当在同一页面上的其他组件上时,将使用以下键格式:key={`home_categories_${index + 1}`}

希望它对您有用!