React Hook Form v7.39.4:跨文件获取useFieldArray的fields正确类型
React Hook Form useFieldArray 类型问题
我希望useFieldArray返回的fields具备正确类型(类似FieldArrayWithId<{name: string; age: number}, "users", "id">[]),这样就能正常映射并访问name和age属性。但在跨文件使用时,fields的类型始终是Record<"id", string>[],无法正确识别子属性。
我已经尝试过以下方案:
- 在其他文件的
useForm中指定泛型 - 为
fields强制断言正确类型 - 将
useFormContext中的control传入useFieldArray(尽管官方文档说明该参数为可选)
解决方案
1. 统一定义表单类型并在根组件useForm中明确指定
先在单独的类型文件(比如types.ts)里定义完整的表单结构:
export type User = { name: string; age: number; }; export type FormValues = { users: User[]; };
在根组件初始化useForm时,严格传入这个泛型:
import { useForm } from "react-hook-form"; import { FormValues } from "./types"; const { control, register } = useForm<FormValues>({ defaultValues: { users: [{ name: "", age: 0 }] } });
2. 在子组件中为useFieldArray指定泛型
跨文件的子组件里使用useFieldArray时,必须显式传入表单值类型和字段名的泛型参数,确保类型推导正确:
import { useFieldArray, FieldArrayWithId } from "react-hook-form"; import { FormValues, User } from "./types"; const { fields, append, remove } = useFieldArray<FormValues, "users">( { control, // 必须传入根组件的control,确保上下文类型一致 name: "users" } ); // 此时fields的类型为FieldArrayWithId<User, "users", "id">[],可直接访问name和age fields.map((field) => ( <div key={field.id}> <input {...register(`users.${field.id}.name`)} /> <input type="number" {...register(`users.${field.id}.age`)} /> </div> ));
3. 依赖正确的上下文传递,避免类型断言
不要用as强制断言fields类型,这会掩盖潜在的类型问题。确保control是从根组件的useForm实例传递过来的(无论是通过props还是FormProvider),这样useFieldArray就能自动继承正确的类型。
如果使用FormProvider,确保根组件的control被正确注入:
import { FormProvider } from "react-hook-form"; // 根组件 const formMethods = useForm<FormValues>({ /* 默认值配置 */ }); return ( <FormProvider {...formMethods}> <UserList /> </FormProvider> ); // 子组件UserList import { useFormContext, useFieldArray } from "react-hook-form"; import { FormValues } from "./types"; const { control } = useFormContext<FormValues>(); const { fields } = useFieldArray<FormValues, "users">({ control, name: "users" });
这样处理后,fields就能正确推导为包含name、age和id的类型数组,无需手动断言。
内容的提问来源于stack exchange,提问作者djowvani
相关产品推荐
相关产品推荐

