You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React列表报unique 'key' prop错误,已设唯一person.id仍无效如何解决?

问题根本原因
  • 第一个警告的成因:你所验证的person.id全局唯一不代表它在每次渲染的单组rowList中都是有效值,大概率存在个别项的person.id为undefined、null、空字符串,或是同个rowList内出现重复id,导致同个map循环下出现重复key,拼接索引后相当于给key加了兜底校验,因此第一个警告消失。
  • 第二个警告的成因:90%以上概率是你的ImageComponent内部存在数组map渲染JSX的逻辑,且返回的最外层元素没有设置唯一key,你之前只排查了RowComponent层级的key,没有检查子组件内部的列表渲染逻辑。
完整解决办法
  1. 验证rowList内所有项的id有效性:在RowComponent的map循环中打印每一项person.id,确认无无效值、同组内无重复,如果确认所有id都有效,完全可以去掉拼接的索引,直接用person.id作为key即可。
  2. 检查ImageComponent的代码:找到所有数组调用map返回JSX的逻辑,给返回的最外层JSX元素添加当前map循环内的唯一key即可解决第二个警告。
  3. 额外优化(可选):当前GamePage每次重渲染都会重新生成随机列表,建议用useMemo缓存计算结果,减少不必要的重渲染和diff阶段的异常:
import React, { useMemo } from 'react'
import { Grid, Image } from 'semantic-ui-react'

const RowComponent = ({ rowList, personToFind }) => 
  <Grid.Row columns={3} centered>
    {rowList.map(person =>
      <Grid.Column key={person.id}>
        <ImageComponent person={person} personToFind={personToFind} />
      </Grid.Column>)
    }   
  </Grid.Row>

const GamePage = React.memo(({ peopleList }) => {
  // 缓存随机列表计算逻辑,仅当peopleList变化时重新生成
  const randomPeopleList = useMemo(() => getNRandomItems(peopleList, 6), [peopleList])
  const topRow = useMemo(() => randomPeopleList.slice(0, 3), [randomPeopleList])
  const bottomRow = useMemo(() => randomPeopleList.slice(3), [randomPeopleList])
  const personToFind = useMemo(() => getRandomItem(randomPeopleList), [randomPeopleList])
  
  return (
    <Grid>
      <RowComponent rowList={topRow} personToFind={personToFind} />
      <RowComponent rowList={bottomRow} personToFind={personToFind} />
    </Grid>
  ) 
})

如果完成上述操作后警告仍存在,可以查看控制台报错的完整信息,报错信息会明确标注触发警告的组件名称,直接定位到对应组件的列表渲染逻辑即可。

内容的提问来源于stack exchange,提问作者Nikita Vlasenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 18:54:05