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

React Router路由切换时,React Hook Form defaultValues不更新求助

解决React Router加载器数据更新后React Hook Form默认值不刷新的问题

为什么不能把useForm放在useEffect里

绝对不能这么做。React Hook的核心规则要求必须在组件顶层作用域调用Hook,不能在useEffect、条件判断、循环等嵌套逻辑中调用。违反此规则会触发React的Hook校验错误,导致组件渲染行为异常,比如状态丢失、重复渲染等问题。

正确的解决方案

方案1:使用useForm的reset方法同步数据

当useLoaderData返回的productData更新时,调用reset方法将表单重置为新的默认值。这是最推荐的方式,它不会重新挂载组件,能灵活控制是否保留用户已输入的临时状态。

代码示例:

import { useLoaderData } from 'react-router-dom';
import { useForm, useEffect } from 'react';

const Product = () => {
  const productData = useLoaderData();
  const { register, reset, handleSubmit } = useForm({
    defaultValues: productData
  });

  // 监听productData变化,同步更新表单默认值
  useEffect(() => {
    reset(productData);
  }, [productData, reset]);

  const onSubmit = (data) => {
    // 表单提交逻辑
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('name')} placeholder="产品名称" />
      <input type="number" {...register('price')} placeholder="价格" />
      {/* 其他表单字段 */}
      <button type="submit">提交</button>
    </form>
  );
};

export default Product;

方案2:通过key强制组件重新挂载

如果希望每次切换产品时完全重置表单(包括清空用户输入),可以给组件或表单容器添加一个与productId绑定的key。当productId变化时,React会销毁旧组件并重新挂载新组件,此时useForm会使用新的defaultValues初始化。

代码示例:

import { useLoaderData } from 'react-router-dom';
import { useForm } from 'react-hook-form';

const Product = () => {
  const productData = useLoaderData();
  const { register, handleSubmit } = useForm({
    defaultValues: productData
  });

  const onSubmit = (data) => {
    // 表单提交逻辑
  };

  // 用productId作为key,切换产品时强制重新渲染组件
  return (
    <div key={productData.id}>
      <form onSubmit={handleSubmit(onSubmit)}>
        <input {...register('name')} placeholder="产品名称" />
        <input type="number" {...register('price')} placeholder="价格" />
        {/* 其他表单字段 */}
        <button type="submit">提交</button>
      </form>
    </div>
  );
};

export default Product;

关键原理说明

React Hook Form的defaultValues仅在组件首次挂载时生效,后续即使传入的defaultValues变化,也不会自动同步表单状态。这是因为表单状态由React Hook Form内部维护,不会主动监听外部props的变化,必须通过reset方法手动触发同步,或者通过key触发组件重新初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:05:02