反应警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。检查`App`的渲染方法
Posted
技术标签:
【中文标题】反应警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。检查`App`的渲染方法【英文标题】:React Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `App` 【发布时间】:2017-05-02 12:33:40 【问题描述】:我遇到了这个错误,但我正在定义一个键。这是我抱怨的App.js
。
import React from 'react';
import Relay from 'react-relay';
import AccountTable from './AccountTable';
class App extends React.Component
render()
return (
<div>
<h1>Account list</h1>
this.props.viewer.accounts.edges.map(edge =>
<AccountTable key=edge.node.id account=edge.node />
)
</div>
);
export default Relay.createContainer(App,
fragments:
viewer: () => Relay.QL`
fragment on User
accounts(first: 10)
edges
node
$AccountTable.getFragment('account')
`,
,
);
【问题讨论】:
bob ross 会为你的代码山感到自豪。但实际上你应该检查你的 edge.node.id 的唯一性。 我猜是做通常的健全性检查。上面的代码是错误的 100% 来源吗? ids真的是独一无二的吗?也许你有几个未定义/空值 查看是否有重复的ID:console.log(this.props.viewer.accounts.edges.map(edge => edge.node.id))
所以,edge.node 对象此时没有定义 id。我认为这是因为节点引用了另一个片段。当我在这个片段中拼写出帐户时,我没有这个问题。当我将帐户 graphql 的东西分解成它自己的片段时,这出现了。你们中有人知道解决方法吗?
【参考方案1】:
纠正此问题的最简单方法是将键基于地图的索引:
this.props.viewer.accounts.edges.map((edge, i) =>
<AccountTable key=i account=edge.node />
)
那么,您不必担心edge.node.id
的值有多独特。 key
只需要在所有 AccountTable
同级的上下文中是唯一的。它不需要是全球唯一的。所以,索引运行良好。
但是,如果您有一个基于对象的稳定 id,那显然更好。
【讨论】:
根据 react 文档:“当您没有用于渲染项目的稳定 ID 时,您可以使用项目索引作为键作为最后的手段”。因此,我想确保在执行此操作之前无法获得稳定的 id。在这方面有什么建议,还是因为我的节点引用了不同的片段而这不可能? 好吧,除非你有另一个 id,否则这可能是你的“最后手段”,对吧? 它确实解决了这个问题。我将进行更多挖掘,但如果我找不到获取对象 id 的方法,我会将其标记为解决方案。谢谢! 如果使用item index作为key,在数组重新排序的情况下可能会失效:***.com/a/43892905/960857【参考方案2】:我使用的方案是把relay fragment的底层id提取为key
this.props.viewer.accounts.edges.map((edge) =>
edge && e.node && <AccountTable key=edge.node.__id account=edge.node />
)
【讨论】:
以上是关于反应警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。检查`App`的渲染方法的主要内容,如果未能解决你的问题,请参考以下文章
警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。检查“搜索”的渲染方法
警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。检查`Units`的渲染方法
警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。检查`MovieResults`的渲染方法