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

React嵌套列表渲染key prop警告排查与解决

问题描述

React 开发过程中控制台抛出 Warning: Each child in a list should have a unique "key" prop 警告,当前采用双层循环嵌套的渲染结构,实现代码如下:

import { useState } from "react";

const SIZE_ARRAY = [
  {
    label: "Small",
    value: "sm"
  },
  {
    label: "Medium",
    value: "md"
  },
  {
    label: "Large",
    value: "lg"
  }
];

const DEVICE_ARRAY = [
  {
    deviceLabel: "PC",
    deviceValue: "pc"
  },
  {
    deviceLabel: "Tablet",
    deviceValue: "tablet"
  },
  {
    deviceLabel: "Mobile",
    deviceValue: "mobile"
  }
];

export default function SampleLoop() {
  const [option, setOption] = useState();

  return (
    <>
      <ul>
        {SIZE_ARRAY.map((size) => {
          const { label, value } = size;
          return (
            <li key={label}>
              <span>Margin : {label}</span>
              {DEVICE_ARRAY.map((device) => {
                const { deviceLabel, deviceValue } = device;
                return (
                  <>
                    <input
                      key={deviceLabel}
                      onChange={(newValue) => {
                        setOption({
                          ...option,
                          margin_size: {
                            ...option.margin_size,
                            [value]: {
                              ...option.margin_size[value],
                              [deviceValue]: newValue
                            }
                          }
                        });
                      }}
                    />
                  </>
                );
              })}
            </li>
          );
        })}
      </ul>
    </>
  );
}

已为外层<li>元素、内层<input>元素添加key属性,但警告仍未消除。

问题原因

key 属性必须绑定在数组遍历方法(如map)直接返回的根级元素上,React 仅会对遍历直接返回的子元素做key合法性校验。
当前代码内层DEVICE_ARRAY.map直接返回的是空Fragment短语法(<></>),这才是React识别到的列表子元素。key被错误绑定在Fragment内部的<input>上,React无法识别到对应列表项的key,因此警告持续存在。
额外注意:空Fragment短语法<></>不支持传入任何属性,包括key。

修复方案

二选一即可:

  • 方案1:移除内层多余的空Fragment包裹,直接将<input>作为map返回的根元素,把key绑定在input上。推荐给key拼接外层size的唯一值,保证全局key唯一,避免潜在冲突。
  • 方案2:如果确实需要Fragment作为包裹层,将短语法<></>替换为显式导入的React.Fragment组件,把key绑定在Fragment标签上。

修复后核心代码示例(采用更简洁的方案1)

<li key={label}>
  <span>Margin : {label}</span>
  {DEVICE_ARRAY.map((device) => {
    const { deviceLabel, deviceValue } = device;
    return (
      <input
        key={`${value}-${deviceValue}`}
        onChange={(newValue) => {
          setOption({
            ...option,
            margin_size: {
              ...option?.margin_size,
              [value]: {
                ...option?.margin_size?.[value],
                [deviceValue]: newValue
              }
            }
          });
        }}
      />
    );
  })}
</li>

修复代码中额外增加了可选链?.,避免初始状态下option.margin_size为undefined时读取属性报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:06:21