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

Formik渲染字段列表时React触发唯一key prop警告求助

解决React列表key警告问题

问题根源

你的代码里有两处引发警告的问题:

  1. 下拉选项<option>循环渲染时没加唯一key
  2. 外层div用index当key(虽能临时消警告,但不是最优方案)

修复步骤

1. 给下拉选项补全key

在field.options.map的<option>上添加key={option.value},因为选项的value本身是唯一标识:

{field.options.map((option) => (
  <option key={option.value} value={option.value}>
    {option.label}
  </option>
))}

2. 替换index为更稳定的key

把外层div的key={index}换成key={field.name}——表单字段的name属性天生唯一,比index更稳定(数组元素顺序变化时,React不会误判元素身份):

{fields.map((field) => (
  <div key={field.name}>
    {/* 原有表单元素代码 */}
  </div>
))}

3. (可选)移除多余的FieldArray组件

你当前没用到Formik FieldArray的数组操作能力,只是用它包裹了自己的fields循环,直接移除FieldArray、直接渲染循环即可,代码更简洁:

// 删掉<FieldArray>标签,直接写循环
{fields.map((field) => (
  <div key={field.name}>
    {/* 原有内容 */}
  </div>
))}

修复后的关键代码片段

<Formik
  initialValues={initialValues}
  onSubmit={onSubmit}
  validate={validate}
>
  {({ values, handleSubmit, handleChange, errors }: formikProps) => (
    <form
      onSubmit={handleSubmit}
      className={`space-y-4 sm:space-y-0 ${
        formType === "login"
          ? ""
          : "sm:grid sm:grid-cols-2 sm:grid-rows-[auto_auto_auto_auto_auto_40px]"
      } flex flex-col  gap-4`}
    >
      {fields.map((field) => (
        <div key={field.name}>
          <label
            htmlFor={field.name}
            className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
          >
            {field.label}
          </label>
          {field.options && (
            <select
              name={field.name}
              value={values[field.name]}
              onChange={handleChange}
              className="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
              data-testid={`${field.name}-input`}
            >
              {field.options.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          )}
          {!field.options && (
            <input
              type={field.type}
              name={field.name}
              value={values[field.name]}
              onChange={handleChange}
              placeholder={field.placeholder}
              className="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
              data-testid={`${field.name}-input`}
            />
          )}
          {errors[field.name] && (
            <div className="text-red-500 text-xs italic">
              {errors[field.name]}
            </div>
          )}
        </div>
      ))}
      <Button type="submit" className="w-full col-span-2">
        {submitLabel}
      </Button>
      <span className="text-xs text-gray-500 dark:text-gray-400">
        {message}
      </span>
    </form>
  )}
</Formik>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 02:25:17