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

使用@conform-to/react的getInputProps时React key prop展开报错

问题:React提示key prop被展开到JSX元素中(未显式传递key)

我遇到一个问题:即使未手动传递key prop,React仍报错提示key prop被展开到JSX元素中。相关代码使用了Conform的getInputProps方法。

相关代码片段

<Input
  className="mb-[20px]"
  label="First Name"
  errorMessage={fields.firstName.errors?.at(0)}
  {...getInputProps(fields.firstName, { type: "text" })}
/>

错误信息

A props object containing a "key" prop is being spread into JSX:
  let props = {key: someKey, className: ..., label: ..., errorMessage: ..., required: ..., id: ..., name: ..., form: ..., type: ..., minLength: ...};
  <Input {...props} />
React keys must be passed directly to JSX without using spread:
  let props = {className: ..., label: ..., errorMessage: ..., required: ..., id: ..., name: ..., form: ..., type: ..., minLength: ...};
  <Input key={someKey} {...props} />

完整表单代码

"use client";

import { useActionState } from "react";
import { getFormProps, getInputProps, useForm } from "@conform-to/react";
import { getZodConstraint, parseWithZod } from "@conform-to/zod";

import { signUpWithDetails } from "@/features/authentication/actions";
import { SignUpSchema } from "@/features/authentication/schemas/sign-up";

import { Input } from "@/common/components/Form/Input/Input";
import { Button } from "@/common/components/Form/Button/Button";
import { DatePicker } from "@/common/components/Form/DatePicker/DatePicker";

interface DetailsFormProps {
  email: string;
}

export const DetailsForm = ({ email }: DetailsFormProps) => {
  const [lastResult, action, pending] = useActionState(
    signUpWithDetails,
    undefined,
  );

  const [form, fields] = useForm({
    lastResult,
    constraint: getZodConstraint(SignUpSchema),
    onValidate({ formData }) {
      return parseWithZod(formData, { schema: SignUpSchema });
    },
    shouldValidate: "onSubmit",
    shouldRevalidate: "onInput",
  });

  return (
    <form className="w-full" action={action} {...getFormProps(form)}>
      <input type="hidden" name="email" value={email} />
      <Input
        className="mb-[20px]"
        label="First Name"
        errorMessage={fields.firstName.errors?.at(0)}
        {...getInputProps(fields.firstName, { type: "text" })}
      />
      <Input
        className="mb-[20px]"
        label="Last Name"
        errorMessage={fields.lastName.errors?.at(0)}
        {...getInputProps(fields.lastName, { type: "text" })}
      />
      <DatePicker
        className="mb-[20px]"
        label="Date of Birth"
        max={new Date().toJSON().slice(0, 10)}
        errorMessage={fields.dateOfBirth?.errors?.at(0)}
        {...getInputProps(fields.dateOfBirth, { type: "date" })}
      />
      <Input
        className="mb-10"
        label="Password"
        errorMessage={fields.password.errors?.at(0)}
        {...getInputProps(fields.password, { type: "password" })}
      />
      <Button
        className="w-full mb-6"
        label="Continue"
        variant="primary"
        type="submit"
        isLoading={pending}
      />
    </form>
  );
};

解决方案

原因

问题出在getInputProps返回的对象中自动包含了key属性,但React要求key必须直接传递给JSX元素,不能通过对象展开的方式传递。

解决方法

直接解构getInputProps的返回值,排除key后再展开剩余属性:

方式1:内联解构

<Input
  className="mb-[20px]"
  label="First Name"
  errorMessage={fields.firstName.errors?.at(0)}
  {...(({ key, ...rest }) => rest)(getInputProps(fields.firstName, { type: "text" }))}
/>

方式2:提前处理props

// 先获取并处理props
const firstNameProps = getInputProps(fields.firstName, { type: "text" });
const { key, ...firstNameInputProps } = firstNameProps;

// 渲染Input时使用处理后的props
<Input
  className="mb-[20px]"
  label="First Name"
  errorMessage={fields.firstName.errors?.at(0)}
  {...firstNameInputProps}
/>

因为这些Input组件并非在列表循环中渲染,所以这个自动生成的key没有实际作用,排除后不会影响功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 22:30:05