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

使用React Context与React Hook Form时组件状态不更新问题

React Context FormProvider 数据更新后消费组件无法同步的问题排查与解决

问题核心原因

你的代码中FormMenus组件作为FormProvider的父级,不在Provider的作用域内,却调用了useFormContext,导致拿到的是Context的默认空对象{},而非Provider内部维护的formData状态。

无论子组件如何调用updateFormData更新Provider内的状态,FormMenus里的formData始终是初始空值,因为它根本没接入Provider的上下文。


解决方案

方案1:拆分内部组件处理提交逻辑

把需要访问上下文的提交逻辑移到FormProvider内部的子组件中,确保其处于Context作用域内:

import { useState } from "react";
import { FormProvider, useFormContext } from "src/contexts/form-context";

// 内部组件:在Provider范围内,可正常访问上下文
const FormContent = () => {
  const { formData } = useFormContext();
  const [isSuccessModalOpen, setIsSuccessModalOpen] = useState(false);

  const handleSubmit = async () => {
    try {
      console.log("formData antes do envio:", formData);
      const response = await axios.post("http://localhost:5000/api/member/", formData);
      console.log("Resposta do servidor:", response.data);
      setIsSuccessModalOpen(true); 
    } catch (error) {
      console.error("Error when sending form data:", error);
    }
  };

  return (
    <div sx={{ bgColor: "neutral.200" }}>
      {/* 放置你的表单子组件,它们需用useFormContext调用updateFormData */}
      <Button
        onClick={handleSubmit}
        variant="contained"
        color="success"
        sx={{ m: 1, mr: 2, mt: 2 }}
      >
        Submit
      </Button>
    </div>
  );
};

const FormMenus = () => {
  // 此处不调用useFormContext,因为不在Provider范围内
  return (
    <FormProvider>
      <FormContent />
    </FormProvider>
  );
};

export default FormMenus;

方案2:提升FormProvider到更高层级

如果需要在FormMenus中直接访问上下文,可把FormProvider移到FormMenus的父组件中,让FormMenus处于Provider作用域内:

// 示例:在App组件中包裹Provider
import { FormProvider } from "src/contexts/form-context";
import FormMenus from "./FormMenus";

const App = () => {
  return (
    <FormProvider>
      <FormMenus />
    </FormProvider>
  );
};

// 此时FormMenus可正常调用useFormContext
const FormMenus = () => {
  const { formData } = useFormContext();
  const [isSuccessModalOpen, setIsSuccessModalOpen] = useState(false);

  const handleSubmit = async () => {
    try {
      console.log("formData antes do envio:", formData);
      const response = await axios.post("http://localhost:5000/api/member/", formData);
      console.log("Resposta do servidor:", response.data);
      setIsSuccessModalOpen(true); 
    } catch (error) {
      console.error("Error when sending form data:", error);
    }
  };

  return (
    <div sx={{ bgColor: "neutral.200" }}>
      {/* 表单子组件 */}
      <Button
        onClick={handleSubmit}
        variant="contained"
        color="success"
        sx={{ m: 1, mr: 2, mt: 2 }}
      >
        Submit
      </Button>
    </div>
  );
};

额外检查点

确保所有需要更新表单数据的子组件都在FormProvider包裹下,并且正确使用useFormContext调用updateFormData,例如:

import { useFormContext } from "src/contexts/form-context";

const UsernameField = () => {
  const { updateFormData } = useFormContext();

  const handleChange = (e) => {
    updateFormData({ username: e.target.value });
  };

  return <input name="username" onChange={handleChange} />;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:25:56