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

React Hook Form Controller组件挂载时自动更新值的实现问题

问题解答

核心结论:不能在render方法/函数组件渲染逻辑内设置值

React要求组件的渲染阶段是纯函数,不能包含副作用(比如调用onChange修改外部状态)。如果在render里直接调用onChange,会触发状态更新,进而导致组件重新渲染,再次执行render逻辑,形成无限重渲染循环,这是React严格禁止的行为。

原问题原因分析

你在TestInput的useEffect中调用onChange触发field.onChange,理论上会更新React Hook Form的表单状态,Controller应该感知到状态变化,重新传递更新后的field.value给TestInput,从而触发组件重新渲染。如果没生效,可能的原因包括:

  • 表单初始值与你设置的'AutoSet'相同,状态未发生变化,所以没有触发重渲染
  • useEffect的执行时机问题(挂载时执行,但此时Controller的表单状态还未完成初始化)

正确解决方案

方案1:修正组件内部逻辑,确保状态更新能触发重渲染

保证TestInput的副作用依赖项正确,同时让onChange能正确传递到父组件更新表单状态:

type TProps = {
  value: string;
  onChange?: (value: string) => void;
};
const TestInput = ({ onChange, value }: TProps) => {
  // 模拟组件内部的数据请求逻辑
  useEffect(() => {
    const fetchData = async () => {
      // 替换为实际的异步请求
      const result = await Promise.resolve('AutoSet');
      onChange?.(result);
    };
    fetchData();
  }, [onChange]); // 添加onChange到依赖项,避免闭包问题

  return <div>{value || 'empty'}</div>;
};

type Props = {
  name: string;
  control: Control<FieldValues>;
};
const TestInputController = ({ name, control }: Props) => {
  return (
    <Controller
      control={control}
      render={({ field }) => {
        return (
          <TestInput
            value={field.value}
            onChange={(value) => {
              field.onChange(value);
            }}
          />
        );
      }}
      name={name}
      defaultValue="" // 设置初始值为空,确保状态变化能被感知
    />
  );
};

方案2:直接使用React Hook Form的setValue操作表单状态

如果数据请求逻辑可以放在TestInputController中,直接用setValue更符合React Hook Form的使用规范:

const TestInputController = ({ name, control }: Props) => {
  const { setValue } = control;

  useEffect(() => {
    const fetchData = async () => {
      const result = await Promise.resolve('AutoSet');
      setValue(name, result);
    };
    fetchData();
  }, [name, setValue]);

  return (
    <Controller
      control={control}
      render={({ field }) => {
        return <TestInput value={field.value} onChange={field.onChange} />;
      }}
      name={name}
      defaultValue=""
    />
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 06:27:41