使用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
相关产品推荐
相关产品推荐

