React:使用 @conform-to/react 中的 getInputProps 将“key”Prop 传播到 JSX 中

问题描述 投票:0回答:1

我遇到了一个问题,React 抱怨一个关键 prop 被传播到 JSX 元素中,即使我没有明确地将它作为 props 的一部分传递。

以下是相关代码片段:

<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} />

符合文档:https://conform.guide/api/react/getInputProps

以下是完整表格:

"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>
  );
};
javascript reactjs typescript forms next.js
1个回答
0
投票

在 React 中使用 key 属性时,将其放置在展开运算符之前非常重要。

key 属性帮助 React 更有效地识别和管理列表中的元素,特别是当列表发生变化时(例如添加、删除或重新排序项目)。

如果将键放在扩展运算符之后,则键的值可能会被您正在扩展的对象中的属性覆盖。这可能会导致意外行为,因为 React 可能无法正确分配密钥

不正确

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

正确

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

参考:https://github.com/vercel/next.js/issues/55642#issuecomment-1728746491

© www.soinside.com 2019 - 2024. All rights reserved.