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

React Hook Form表单变化时useEffect未触发的原因及解决方法

问题原因分析

你提供的示例里,useEffect的触发依赖是reset函数和student状态,但用户填写表单时,表单数据存在React Hook Form的内部状态中,并没有更新你定义的student状态,所以依赖项没有变化,自然不会触发这个useEffect。原示例中的useEffect只是用来在student初始化后重置表单值,并非用于监听用户输入。

实时监听表单数据的方法

React Hook Form自带watch API,专门用来监听表单字段的变化,结合useEffect就能实现实时监听需求:

方法1:监听所有表单字段

通过watch()获取所有表单字段的实时值,再在useEffect中监听这个值的变化:

import React, { useState, useEffect } from "react";
import { useForm } from "react-hook-form";

export default function SimpleForm() {
  const { register, handleSubmit, reset, formState, watch } = useForm();
  const [student, initStudent] = useState(null);
  // 监听所有表单字段的实时值
  const formValues = watch();

  useEffect(() => {
    setTimeout(
      () =>
        initStudent({
          name: "Little Johnny",
          email: "lil@johnny.com",
          grade: "3rd",
        }),
      1200
    );
  }, []);

  useEffect(() => {
    console.log("updating.,..");
    reset(student);
  }, [reset, student]);

  // 实时监听表单数据变化
  useEffect(() => {
    console.log("表单数据实时变化:", formValues);
    // 这里可以添加你需要的业务逻辑
  }, [formValues]);

  function onFormSubmit(dataRes) {
    console.log(dataRes);
    return false;
  }

  return (
    <div>
      <h2 className="mb-3">
        React Initiate Form Values in useEffect Hook Example
      </h2>

      {student && (
        <form onSubmit={handleSubmit(onFormSubmit)}>
          <div className="form-group mb-3">
            <label>Name</label>
            <input
              type="text"
              name="name"
              {...register("name")}
              className="form-control"
            />
          </div>

          <div className="form-group mb-3">
            <label>Email</label>
            <input
              type="email"
              name="email"
              {...register("email")}
              className="form-control"
            />
          </div>

          <div className="form-group mb-3">
            <label>Grade</label>
            <input
              type="text"
              name="grade"
              {...register("grade")}
              className="form-control"
            />
          </div>

          <button type="submit" className="btn btn-dark">
            Send
          </button>
        </form>
      )}
      {!student && (
        <div className="text-center p-3">
          <span className="spinner-border spinner-border-sm align-center"></span>
        </div>
      )}
    </div>
  );
}

方法2:监听单个/指定字段

如果只需要关注特定字段,比如name,可以针对性监听:

const nameValue = watch('name');

useEffect(() => {
  console.log("姓名变化了:", nameValue);
}, [nameValue]);

如果要监听多个指定字段,用数组传入即可:

const [nameValue, emailValue] = watch(['name', 'email']);

useEffect(() => {
  console.log("姓名或邮箱变化了:", nameValue, emailValue);
}, [nameValue, emailValue]);

补充说明

  • watch会返回当前表单字段的实时值,用户每次输入都会更新这个值,因此对应的useEffect会同步触发。
  • 若需要监听表单的“是否被修改”状态,可以使用formState.dirtyFields,它会记录所有被修改过的字段,同样可以放到useEffect的依赖中监听。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 22:48:34