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

React中父组件如何访问react-hook-form的setValue等方法?

问题描述

我正在使用react-hook-form库通过JSON构建表单,目前无法在父组件(App组件)中访问该hook的setValue、getValue等方法。我希望在下拉框选项变更时,能在父组件的onChange函数中调用setValue方法,询问是否可以通过创建新的Provider/Context包裹FormBuilder组件,或者使用ref,以及是否可以创建包装hook来实现该需求。

相关代码:

function App() {
  // const methods = useForm();

  const onChange = () => {
    console.log("000000");
    //methods.setValue("firstName", "asdasd");
  };

  // const { registerState, handleSubmit } = methods;

  const onSubmit = (data) => {
    console.log(data);
  };
  return (
    <FormBuilder
      jsonSchema={json}
      defaultValue={defaultValue}
      onSubmitHandler={onSubmit}
      functionHandler={{
        onChange: onChange
      }}
    />
  );
}
解决方案

以下三种方案都能实现父组件访问react-hook-form方法的需求,可根据项目场景选择:

1. 使用Context/Provider传递表单方法

在FormBuilder内部创建Context,将初始化后的react-hook-form方法通过Provider暴露,父组件通过自定义Hook获取这些方法。

  • 步骤1:在FormBuilder文件中创建Context和自定义Hook
import { createContext, useContext } from 'react';
import { useForm } from 'react-hook-form';

const FormMethodsContext = createContext(null);

export const useFormMethods = () => {
  const context = useContext(FormMethodsContext);
  if (!context) throw new Error('useFormMethods必须在FormMethodsProvider内部使用');
  return context;
};
  • 步骤2:FormBuilder中用Provider包裹表单
function FormBuilder({ jsonSchema, defaultValue, onSubmitHandler, functionHandler }) {
  const methods = useForm({ defaultValues: defaultValue });
  const { handleSubmit } = methods;

  return (
    <FormMethodsContext.Provider value={methods}>
      <form onSubmit={handleSubmit(onSubmitHandler)}>
        {/* 这里放你的JSON表单渲染逻辑 */}
      </form>
    </FormMethodsContext.Provider>
  );
}
  • 步骤3:父组件中获取方法并使用
import { useFormMethods } from './FormBuilder';

function App() {
  const methods = useFormMethods();

  const onChange = () => {
    methods.setValue("firstName", "asdasd");
  };

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <FormBuilder
      jsonSchema={json}
      defaultValue={defaultValue}
      onSubmitHandler={onSubmit}
      functionHandler={{ onChange }}
    />
  );
}

2. 使用Ref获取表单方法

通过React的useRef在父组件创建容器,FormBuilder初始化表单方法后将其挂载到ref上,父组件直接访问ref.current调用方法。

  • 步骤1:父组件创建ref并传递给FormBuilder
import { useRef } from 'react';

function App() {
  const formMethodsRef = useRef(null);

  const onChange = () => {
    if (formMethodsRef.current) {
      formMethodsRef.current.setValue("firstName", "asdasd");
    }
  };

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <FormBuilder
      jsonSchema={json}
      defaultValue={defaultValue}
      onSubmitHandler={onSubmit}
      functionHandler={{ onChange }}
      formMethodsRef={formMethodsRef}
    />
  );
}
  • 步骤2:FormBuilder接收ref并赋值
import { useEffect } from 'react';
import { useForm } from 'react-hook-form';

function FormBuilder({ jsonSchema, defaultValue, onSubmitHandler, functionHandler, formMethodsRef }) {
  const methods = useForm({ defaultValues: defaultValue });
  const { handleSubmit } = methods;

  useEffect(() => {
    formMethodsRef.current = methods;
    return () => {
      formMethodsRef.current = null;
    };
  }, [methods, formMethodsRef]);

  return (
    <form onSubmit={handleSubmit(onSubmitHandler)}>
      {/* 这里放你的JSON表单渲染逻辑 */}
    </form>
  );
}

3. 自定义包装Hook

把表单初始化逻辑抽成自定义Hook,父组件调用Hook获取方法后传递给FormBuilder,适合需要在父组件提前处理表单逻辑的场景。

  • 步骤1:创建自定义Hook
import { useForm } from 'react-hook-form';

export const useJsonForm = (defaultValues) => {
  const methods = useForm({ defaultValues });
  return methods;
};
  • 步骤2:父组件调用Hook并传递给FormBuilder
import { useJsonForm } from './hooks';

function App() {
  const methods = useJsonForm(defaultValue);
  const { handleSubmit } = methods;

  const onChange = () => {
    methods.setValue("firstName", "asdasd");
  };

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <FormBuilder
      jsonSchema={json}
      methods={methods}
      onSubmitHandler={onSubmit}
      functionHandler={{ onChange }}
    />
  );
}
  • 步骤3:FormBuilder接收并使用methods
function FormBuilder({ jsonSchema, methods, onSubmitHandler, functionHandler }) {
  const { handleSubmit } = methods;

  return (
    <form onSubmit={handleSubmit(onSubmitHandler)}>
      {/* 这里用methods.register渲染表单字段 */}
    </form>
  );
}

内容的提问来源于stack exchange,提问作者user5711656

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:15:29