我刚刚开始使用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,那么避免此警告的最佳解决方案是什么?
谢谢!
答案 0 :(得分:3)
如果您没有项目的唯一属性(非唯一原语列表),则可以使用索引。
注意:如果项目具有唯一id
(并且应该是非基元列表),则不要使用索引,因为它是{{ 3}}
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;
答案 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}`}
希望它对您有用!