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

