使用Formik提交表单时无法获取isSubmitting加载状态的问题
Formik提交表单时无法获取isSubmitting加载状态的问题
我完全懂你遇到的困扰——当点击模态框里的提交按钮时,没法访问Formik的isSubmitting状态,导致没法正确处理加载状态对吧?这其实是因为你的模态框组件不在Formik的上下文范围内,所以拿不到它提供的状态值。
问题根源
你原来的代码里,Modal是通过useMemo在组件顶层创建的,它不在Formik的render回调闭包里面。Formik传递的isSubmitting等状态只有在它的render回调内部(或者使用Formik上下文钩子的组件)才能访问到,所以模态框里的按钮自然拿不到这个状态。
解决方案一:把模态框移到Formik的render回调内部
最简单的办法就是把模态框的渲染逻辑直接放到Formik提供的回调函数里,这样就能直接拿到isSubmitting:
import React, { useState } from "react"; import { Formik, Form, Field } from "formik"; const FormWithModal = () => { const [isModalOpen, setModalOpen] = useState(false); return ( <div> <h1>Form with Modal</h1> <Formik initialValues={{ numberInput: "" }} onSubmit={async (values, { setSubmitting }) => { setSubmitting(true); // 模拟异步操作 await new Promise((resolve) => setTimeout(resolve, 1000)); setModalOpen(true); setSubmitting(false); }} > {({ isSubmitting }) => ( <Form> <div> <label htmlFor="numberInput">Number:</label> <Field id="numberInput" name="numberInput" type="number" placeholder="Enter a number" /> </div> <button type="submit" disabled={isSubmitting}> 打开模态框 </button> {/* 把模态框移到这里,直接访问isSubmitting */} {isModalOpen && ( <div className="modal"> <div className="modal-content"> <h2>Modal</h2> <p>The form has been submitted!</p> {/* 现在这个按钮能拿到isSubmitting了 */} <button type="submit" disabled={isSubmitting}> 确认提交 </button> </div> </div> )} </Form> )} </Formik> </div> ); }; export default FormWithModal;
解决方案二:用useFormikContext钩子单独封装模态框
如果你想把模态框做成独立的可复用组件,可以用Formik提供的useFormikContext钩子,在模态框内部直接获取Formik的状态:
import React, { useState } from "react"; import { Formik, Form, Field, useFormikContext } from "formik"; // 独立的模态框组件 const SubmitModal = ({ isOpen, onClose }) => { if (!isOpen) return null; // 通过useFormikContext获取Formik的状态 const { isSubmitting } = useFormikContext(); return ( <div className="modal"> <div className="modal-content"> <h2>Modal</h2> <p>The form has been submitted!</p> <button type="submit" disabled={isSubmitting}> 确认提交 </button> <button onClick={onClose}>取消</button> </div> </div> ); }; const FormWithModal = () => { const [isModalOpen, setModalOpen] = useState(false); return ( <div> <h1>Form with Modal</h1> <Formik initialValues={{ numberInput: "" }} onSubmit={async (values, { setSubmitting }) => { setSubmitting(true); await new Promise((resolve) => setTimeout(resolve, 1000)); setModalOpen(true); setSubmitting(false); }} > {({ isSubmitting }) => ( <Form> <div> <label htmlFor="numberInput">Number:</label> <Field id="numberInput" name="numberInput" type="number" placeholder="Enter a number" /> </div> <button type="submit" disabled={isSubmitting}> 打开模态框 </button> {/* 渲染独立的模态框组件 */} <SubmitModal isOpen={isModalOpen} onClose={() => setModalOpen(false)} /> </Form> )} </Formik> </div> ); }; export default FormWithModal;
这两种方式都能解决你拿不到isSubmitting的问题,第一种更简单直接,第二种适合需要复用模态框的场景。
备注:内容来源于stack exchange,提问作者new coderrrr
相关产品推荐
相关产品推荐

