在react-admin表单中使用useFormState报错,表单上下文为null
问题:React-Admin表单中使用React-Hook-Form的useFormState报错
我尝试在react-admin的表单中使用react-hook-form的useFormState钩子,作为两个模块的初学者,查阅官方文档后没发现明显使用错误,但一直遇到错误:Cannot read properties of null (reading 'control')。
我知道这个错误通常意味着钩子调用不在FormProvider中,但我的自定义组件明明嵌套在Form组件内部。在组件中添加useFormContext打印上下文,结果返回null。
我的代码如下:
import { useFormState } from 'react-hook-form'; import { Create, Form, TextInput, } from 'react-admin'; const MyCustomComponent = () => { const { errors, isDirty } = useFormState(); return ( <div> <h3>State</h3> <pre>{JSON.stringify({ errors, isDirty }, null, 2)}</pre> </div> ); }; export const CreateComponent = () => ( <Create> <Form> <TextInput source="title" /> <TextInput source="description" /> <MyCustomComponent /> </Form> </Create> );
请问我遗漏了什么?使用TypeScript时是否需要添加默认值?
解决方案
问题核心是react-admin自带的Form组件和react-hook-form的上下文系统不兼容,它有自己独立的表单状态管理机制,并非基于react-hook-form的FormProvider实现,所以直接调用react-hook-form的钩子自然拿不到上下文。
你有两种解决思路:
- 手动集成react-hook-form到react-admin中
- 改用react-admin自带的表单状态钩子
思路1:手动集成react-hook-form
需要自己搭建react-hook-form的表单结构,同时适配react-admin的字段组件:
import { useForm, FormProvider, useFormState } from 'react-hook-form'; import { Create, TextInput, Button } from 'react-admin'; const MyCustomComponent = () => { const { errors, isDirty } = useFormState(); return ( <div> <h3>State</h3> <pre>{JSON.stringify({ errors, isDirty }, null, 2)}</pre> </div> ); }; // 封装适配react-hook-form的TextInput组件 const RhfTextInput = ({ source, ...props }) => { const { register } = useFormContext(); return <TextInput {...register(source, props)} source={source} />; }; export const CreateComponent = () => { const methods = useForm({ defaultValues: { title: '', description: '' } }); const handleSubmit = (data) => { // 这里替换为你的表单提交逻辑,比如调用react-admin的dataProvider console.log('提交的数据:', data); }; return ( <Create> <FormProvider {...methods}> <form onSubmit={methods.handleSubmit(handleSubmit)}> <RhfTextInput source="title" required /> <RhfTextInput source="description" /> <MyCustomComponent /> <Button type="submit" variant="contained" color="primary"> 保存 </Button> </form> </FormProvider> </Create> ); };
思路2:使用react-admin自带的表单状态钩子
如果不需要额外依赖react-hook-form,直接用react-admin提供的同名钩子即可:
// 注意导入的是react-admin的useFormState import { useFormState } from 'react-admin'; import { Create, Form, TextInput, } from 'react-admin'; const MyCustomComponent = () => { // 直接拿到react-admin表单的状态 const { errors, isDirty } = useFormState(); return ( <div> <h3>State</h3> <pre>{JSON.stringify({ errors, isDirty }, null, 2)}</pre> </div> ); }; export const CreateComponent = () => ( <Create> <Form> <TextInput source="title" /> <TextInput source="description" /> <MyCustomComponent /> </Form> </Create> );
关于TypeScript的疑问:不需要额外添加默认值来解决上下文问题,只需给useForm传入对应的表单类型定义即可(集成react-hook-form的场景)。
内容的提问来源于stack exchange,提问作者Paulo-99
相关产品推荐
相关产品推荐

