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

React列表子元素缺少唯一key属性问题求助(含高阶组件场景)

解决React列表"Each child in a list should have a unique 'key' prop"错误

核心问题定位

你的代码中有两处不符合React列表key规范的问题:

  • 嵌套列表中使用无key的React片段
  • 技能列表使用了可能重复的_createdAt作为key

具体修改方案

1. 修复嵌套列表的片段key问题

在experience.works.map迭代中,你用<>包裹了motion.div和Tooltip组件,但简写片段无法添加key。React要求map返回的每个顶级元素必须有唯一key,因此需要替换为带key的完整React.Fragment:

原代码:

{experience.works.map((work:any) => (
  <>
    <motion.div
      whileInView={{ opacity: [0, 1] }}
      transition={{ duration: 0.5 }}
      className="app__skills-exp-work"
      data-tip
      key={work._key}
      id={work._key}
      data-tooltip-delay-hide={500}
      data-tooltip-variant="info"
    >
      <h4 className="bold-text">{work.name}</h4>
      <p className="p-text">{work.company}</p>
    </motion.div>
    <Tooltip
      anchorId={work._key}
      className="skills-tooltip"
      content={work.desc}
      float={true}
      id="tooltip-anchor-10"
    />
  </>
))}

修改后:

{experience.works.map((work:any) => (
  <React.Fragment key={work._key}>
    <motion.div
      whileInView={{ opacity: [0, 1] }}
      transition={{ duration: 0.5 }}
      className="app__skills-exp-work"
      data-tip
      id={work._key}
      data-tooltip-delay-hide={500}
      data-tooltip-variant="info"
    >
      <h4 className="bold-text">{work.name}</h4>
      <p className="p-text">{work.company}</p>
    </motion.div>
    <Tooltip
      anchorId={work._key}
      className="skills-tooltip"
      content={work.desc}
      float={true}
      id="tooltip-anchor-10"
    />
  </React.Fragment>
))}

注:外层Fragment已设置唯一key,可移除motion.div上的重复key,保留也不会报错,但外层key是必须项。

2. 替换技能列表的非唯一key

技能列表中使用skill._createdAt作为key,存在同一时间创建多个技能导致key重复的风险。改用Sanity文档自带的唯一_id字段,确保key绝对唯一:

原代码:

{skills.map((skill) => (
  <motion.div
    className='app__skills-item app__flex'
    whileInView={{ opacity: [0, 1] }}
    transition={{ duration: .5 }}
    key={skill._createdAt}
  >
    ...
  </motion.div>
))}

修改后:

{skills.map((skill) => (
  <motion.div
    className='app__skills-item app__flex'
    whileInView={{ opacity: [0, 1] }}
    transition={{ duration: .5 }}
    key={skill._id}
  >
    ...
  </motion.div>
))}

3. 禁用Math.random()作为key的调试方式

Math.random()会在每次组件渲染时生成新值,破坏React的元素复用机制,不仅无法解决key错误,还可能引发性能问题和组件状态异常,绝对不要使用。


原理说明

React通过key识别列表元素的唯一性,以此优化更新时的组件复用逻辑,避免不必要的重渲染。key必须是稳定、唯一且可预测的值,文档ID(如_id、_key)是最理想的选择;同时map返回的所有顶级元素(包括Fragment)都必须设置key。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:35:21