使用@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
相关产品推荐
相关产品推荐

