reactjs - 使用 shadcn FormField 组件时的类型问题
类型 'foo' 不能赋值给类型 'InputProps'
所以,我正在尝试创建一个可重用的组件,称为 TextInput,它封装了 Shadcn 的 FormField 组件,因为文档显示需要将来自 FormField 渲染方法的 "field" 属性传递给 Input 组件。下面是 TextInput 组件:
import React from "react";
import {
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "./ui/form";
import { Input } from "./ui/input";
import { Control } from "react-hook-form";
type formSchema = {
title: string;
description: string;
image: string;
location: {
number: number;
country: string;
state: string;
district: string;
street: string;
complement: string;
};
};
type control = Control<formSchema, any>;
type name = keyof formSchema;
type Props = {
name: name;
label: string;
placeholder: string;
description?: string;
control: control;
};
const TextInput = ({
name,
label,
placeholder,
description,
control,
}: Props) => {
return (
<FormField
control={control}
name={name}
render={({ field }) => (
<FormItem>
<FormLabel>{label}</FormLabel>
<FormControl>
{/* Here's the problem */}
<Input {...field} placeholder={placeholder} />
</FormControl>
<FormDescription>{description}</FormDescription>
<FormMessage />
</FormItem>
)}
/>
);
};
export default TextInput;
但是当我传递 'field' 属性时,我从 TypeScript 收到了这个错误消息:
类型 ‘{ placeholder: string; onChange: (...event: any[]) => void; onBlur: Noop; disabled?: boolean | undefined; value: string | { number: number; country: string; state: string; district: string; street: string; complement: string; }; name: keyof formSchema; ref: RefCallBack; }’ 不能分配给类型 ‘InputProps’。属性 ‘value’ 的类型不兼容。类型 ‘string | { number: number; country: string; state: string; district: string; street: string; complement: string; }’ 不能分配给类型 ‘string | number | readonly string[] | undefined’。类型 ‘{ number: number; country: string; state: string; district: string; street: string; complement: string; }’ 不能分配给类型 ‘string | number | readonly string[] | undefined’。
我尝试在 shadcn 和 react-hook-form 的文档中以及互联网上搜索,但我找不到任何关于如何处理它的线索。我最近才开始使用 TypeScript,所以以前从未遇到过这样的情况。我也尝试使用 react-hook-form 的 Controller 输入,但仍然出现这个错误。这里是父组件以提供更多上下文:
"use client";
import { Form, FormField } from "./ui/form";
import { SubmitHandler, useForm } from "react-hook-form";
import TextInput from "./TextInput";
import { Button } from "./ui/button";
import formSchema from "@/utils/meetSchema";
import * as z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
const MeetUpForm = () => {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
});
type Inputs = {};
const onSubmit: SubmitHandler<Inputs> = (data) => console.log(data);
return (
<Form {...form}>
<TextInput
control={form.control}
label="Title"
placeholder="Type the meet up title"
name="title"
/>
<TextInput
control={form.control}
label="Description"
placeholder="Type the meet up description"
name="description"
/>
<TextInput
control={form.control}
label="Image"
placeholder="Type the meet up image URL"
name="image"
/>
<h1 className="text-xl font-bold my-4">Location</h1>
<TextInput
control={form.control}
label="Country"
placeholder="Type the meet up country"
name="location"
/>
<TextInput
control={form.control}
label="State"
placeholder="Type the meet up state"
name="location"
/>
<TextInput
control={form.control}
label="District"
placeholder="Type the meet up district"
name="location"
/>
<TextInput
control={form.control}
label="Street"
placeholder="Type the meet up street"
name="location"
/>
<TextInput
control={form.control}
label="Number"
placeholder="Type the meet up number"
name="location"
/>
<TextInput
control={form.control}
label="Complement"
placeholder="Type the meet up location complement"
name="location"
/>
<Button type="submit">Submit</Button>
</Form>
);
};
export default MeetUpForm;
这是一个个人和公共项目,所以你可以在这里查看完整代码:https://github.com/Tonny221/meet-up/tree/dev
欢迎随时给我任何反馈
答案#1
是的,我在我的项目中也遇到了同样的问题,并使用来自“react-hook-form”的 UseFormReturn 类型解决了它。下面我创建了 FormFieldComponent 组件。
有关视频讲解,您可以观看此视频 https://www.youtube.com/watch?v=E3YIY4Xxw88&ab_channel=shirshakKandel
{/* Country and phone */}
<div className="grid lg:grid-cols-2 lg:gap-4">
{/* Country */}
<FormFieldComponent
form={form}
isPending={isPending}
label="Country"
name="country"
/>
{/* Phone Number */}
<FormFieldComponent
form={form}
isPending={isPending}
label="Phone Number(Optional)"
name="phone"
/>
</div>
FormFieldComponent 的定义如下。这里 RegisterSchema 是我使用 zod 创建的 schema。
const FormFieldComponent = ({
form,
isPending,
label,
name,
placeholder = "Type here",
}: {
form: UseFormReturn<z.infer<typeof RegisterSchema>>;
isPending: boolean;
label: string;
name: keyof z.infer<typeof RegisterSchema>;
placeholder?: string;
}) => {
return (
<FormField
control={form.control}
name={name}
render={({ field }) => (
<FormItem>
<FormLabel>{label}</FormLabel>
<FormControl>
<Input {...field} disabled={isPending} placeholder={placeholder} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
);
};
