React Hook Form结合Redux:如何用异步返回值填充表单字段?
用Redux异步数据填充React Hook Form表单的解决方案
这个问题我之前也碰到过,核心在于React Hook Form的defaultValues只会在组件初始化时读取一次,而你的数据是通过异步请求存入Redux的,首次渲染时baz还没获取到值,所以无法通过defaultValues直接填充。正确的做法是在Redux数据更新后,调用React Hook Form提供的reset方法动态设置表单值。
修正后的完整代码示例
import { useSelector, useDispatch } from 'react-redux'; import { useForm } from 'react-hook-form'; export default function Foo() { // 从Redux获取数据 const { baz } = useSelector(state => state.bar); const dispatch = useDispatch(); // 初始化表单,暂时不设置defaultValues(或设为空对象) const { handleSubmit, register, errors, reset, watch, setError } = useForm({ validationSchema }); // 首次渲染触发后端请求,获取数据存入Redux useEffect(() => { dispatch(fetchBaz()); }, [dispatch]); // 监听Redux中baz的变化,当数据加载完成后重置表单值 useEffect(() => { // 避免空值或未初始化时调用reset if (baz && Object.keys(baz).length > 0) { reset(baz); } }, [baz, reset]); return ( // 注意name属性要和baz中的字段名完全匹配 <input key="someKey" name="bazBaz" ref={register} /> ); }
关键说明
异步数据的监听与重置:
第二个useEffect会监听baz的变化,当后端请求完成、Redux中的baz更新后,就会调用reset(baz)将表单字段与Redux数据同步。这是React Hook Form官方推荐的动态更新表单值的方式。避免无效重置:
加入if (baz && Object.keys(baz).length > 0)的判断,是为了防止首次渲染时baz为空对象或undefined的情况下调用reset,导致表单被错误清空。字段名匹配:
表单输入框的name属性必须和baz对象中的字段名完全一致(比如示例中的bazBaz),这样reset才能正确将对应的值填充到输入框中。移除多余的
onChange:
React Hook Form会通过register自动管理表单状态,除非你有自定义的业务逻辑,否则不需要额外添加onChange事件。
内容的提问来源于stack exchange,提问作者Piioo
相关产品推荐
相关产品推荐

