React中Array.map使用key遇警告:key非props,如何正确传递?
key警告并解决问题 首先,咱们来拆解这个警告的核心意思:
"key is not a prop. Trying to access it will result in undefined being returned. If you need to access the same value within the child component, you should pass it as a different prop."
React里的key是一个特殊的内部属性,它的作用是帮助React识别列表中每个元素的唯一性,从而高效地更新DOM。但它不会被当作普通的prop传递给子组件——这就是为什么你在AccountCard里尝试访问this.props.key时会得到undefined,触发了这个警告。
你的操作误区
你在Array.map里把索引i传给了key,这本身没问题(虽然用索引当key不是最优解,后面会说),但你可能误以为key会像lastTransactions一样,能在子组件里直接拿到。实际上React把key保留给自己用,不会暴露给子组件的props。
解决方法:额外传递一个命名prop
如果你需要在AccountCard里用到这个索引值(或者你原本想通过key传递的那个值),只要多传一个名字不同的prop就行,比如叫index、accountIndex或者更贴合业务的名字。
举个例子,修改你的代码片段:
原来的代码(触发警告的写法):
{ this.state.accounts.map(function(account, i){ return ( <AccountCard key={i} lastTransactions={...} /> ) })}
修改后的正确写法:
{ this.state.accounts.map(function(account, i){ return ( <AccountCard key={i} index={i} {/* 新增这个prop,名字随便取,只要不是key就行 */} lastTransactions={...} /> ) })}
之后在AccountCard组件里,你就可以通过this.props.index来获取这个索引值了,完全不会触发警告。
额外优化建议
虽然用索引当key能解决列表渲染的基本问题,但如果你的列表元素会有排序、新增、删除操作,建议用每个account的唯一标识(比如account.id)作为key,这样React能更精准地识别元素变化,避免不必要的组件重渲染,提升性能:
{ this.state.accounts.map(function(account){ return ( <AccountCard key={account.id} {/* 用唯一ID替代索引 */} accountId={account.id} {/* 如果子组件需要,同样额外传递 */} lastTransactions={...} /> ) })}
内容的提问来源于stack exchange,提问作者Craig

