我遇到了常见错误:警告:数组或迭代器中的每个子代都应具有唯一的“键”属性。
通常,找到有问题的代码很容易,但是这次却并非如此。我想知道的是所显示项目的关键值是什么。
(Q)我有一种方法可以查看所呈现的DOM中每个键属性的值?
当我检查反应生成的HTML生成的lists时,我没有看到DOM元素上的key属性(我也不希望看到它),但这就是我要看的。 是否可以设置一个标志来请求React将该键属性值添加到DOM中,以便我可以看到它?
这将使我看到缺少键的地方,或者有两个具有相同值的键(这是我认为的问题)。参见Find Duplicated Key in a complicated React component
[此时,我正在采用一种有条理的方法,一次渲染一个项目,以找出哪个项目有问题,因此我可以归零并找到有问题的代码。
[寻找解决方案时,有很多很好的文章说明了它是如何工作的以及为什么需要密钥,它们显示如下。
相似的问题(与我的问题相同,但没有答案)-Cant find react error which child is missing key prop
关于键如何工作的好问题,一个很好的答案。参见Understanding unique keys for array children in React.js
ReactJS文档中有关使用键和滥用它们的信息。参见https://reactjs.org/docs/lists-and-keys.html#extracting-components-with-keys。
一个有助于解决此问题的npm库。参见https://www.npmjs.com/package/react-key-index
您如何追踪重复的键-Find Duplicated Key in a complicated React component
这里是一些解释,为什么Key很重要,以及如何将其提供给React中的一系列子代:
下面的示例中有三个List组件。如果在Chrome DevTools中打开它,然后单击“随机排序”,您将意识到列表的子项正在更改(它们闪烁),但是在第二个示例中,li
元素中的其他元素也在更改,原因是React是[[删除和重新创建 li
标签。
我
不推荐
第三(JSON.stringify)示例,最好始终依赖于数据结构中的唯一属性,以避免额外的工作。const items = Array(10).fill(null).map((_, idx) => ({ id: idx, title: 'Item '+(idx+1) }));
function List({ children, items, keyProp, indexType }) {
return (
<div style={{ borderBottom: '1px solid black', padding: '1em' }}>
<h2>{children}</h2>
<ul>
{items.map((data, idx) => <li key={indexType === 'dataStructure' ? data[keyProp] : indexType === 'jsonStringify' ? JSON.stringify(data) : idx}>{data.title}</li>)}
</ul>
</div>
);
}
class App extends React.Component {
constructor(props) {
super(props)
this.state = { items };
this.handleRandomize = this.handleRandomize.bind(this);
}
handleRandomize() {
this.setState({ items: items.slice().sort(() => Math.round(Math.random() * 2) - 1) });
}
render() {
return (
<div style={{ background: 'red', marginBottom: '2em' }}>
<button onClick={this.handleRandomize}>Randomize sort</button>
<List items={this.state.items} indexType='dataStructure' keyProp='id'>
<p>List renderd with unique "id" from data structure</p>
</List>
<List items={this.state.items} indexType='arrayIndex'>
<p>List rendered with index of the loop</p>
</List>
<List items={this.state.items} indexType='jsonStringify'>
<p>List rendered with JSON.stringify()</p>
</List>
</div>
)
}
}
ReactDOM.render(<App />, document.querySelector('#root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>