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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 13:43:05