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

使用react-hook-form监听表单字段的最优方案

替代watch+useEffect的方案:使用useWatch

核心推荐用useWatch,这完全符合你基于react-hook-form的表单控制逻辑,不用手动写onChange,还能解决watch作为useEffect依赖的问题。

为什么useWatch适合?

  • 官方专门为需要监听字段变化并触发副作用的场景设计,返回值是引用稳定的(不会像watch那样受渲染优化影响),可以安全作为useEffect的依赖项
  • 完美适配useFormContext和Controller的架构,保持表单状态统一由react-hook-form管理

结合你的场景的示例代码

import { useFormContext, useWatch, useEffect, useState } from 'react-hook-form';

function CategoryDependentComponent() {
  // 从form context获取control
  const { control } = useFormContext();
  // 监听目标select字段(这里假设字段名是category)
  const selectedCategory = useWatch({
    control,
    name: 'category',
    defaultValue: '' // 可选,设置字段默认值
  });

  // 你需要更新的页面状态
  const [pageRelatedState, setPageRelatedState] = useState(null);

  // 安全依赖useWatch返回的值,触发页面状态更新
  useEffect(() => {
    if (selectedCategory) {
      // 这里写你的业务逻辑:比如根据分类请求数据、更新其他状态等
      setPageRelatedState(`当前选中分类:${selectedCategory}`);
      // 示例:fetch(`/api/data?category=${selectedCategory}`).then(res => setPageRelatedState(res.data))
    } else {
      setPageRelatedState(null);
    }
  }, [selectedCategory]);

  return (
    <>
      {/* 你的Controller渲染的select组件 */}
      <Controller
        name="category"
        control={control}
        render={({ field }) => (
          <select {...field}>
            <option value="">请选择分类</option>
            <option value="frontend">前端开发</option>
            <option value="backend">后端开发</option>
            <option value="design">UI设计</option>
          </select>
        )}
      />
      {/* 展示更新后的页面状态 */}
      {pageRelatedState && <div>{pageRelatedState}</div>}
    </>
  );
}

额外说明

  • 如果需要监听多个字段,useWatch支持传入数组形式的name,比如name: ['category', 'subCategory'],返回的是对应字段值的数组,同样可以安全作为useEffect依赖
  • 全程不用手动处理select的onChange,完全依托react-hook-form的表单注册机制,符合你使用它的初衷

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:42:43