You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:28:29