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

React表单提交时MUI LoadingButton禁用状态不生效问题排查

问题诊断

你的Sign In按钮无法进入禁用加载状态的核心错误出在fetch请求的Promise链式调用写法上:

.then(setLoading(false))

这行代码没有把setLoading(false)作为.then()的回调函数传入,而是在Promise链创建的瞬间就直接执行了setLoading(false)。代码实际运行顺序是:

  1. 执行setLoading(true)尝试把按钮设为加载态
  2. 发起fetch请求
  3. 立刻同步执行setLoading(false)把加载态重置,完全不会等待接口返回

这就导致loading状态刚被设为true就被立刻覆盖,哪怕接口请求耗时再长,按钮也不会显示加载状态。
除此之外代码还有一处遗漏:接口请求抛错进入catch分支时,没有重置loading状态,会导致请求失败后按钮永久卡在加载态。

修复方法
  • 把.then()中直接执行的状态重置逻辑改为回调形式,确保等待前面的Promise执行完成后再修改状态
  • 在请求结束的所有分支(成功/失败)都补充setLoading(false)逻辑,避免状态异常
  • (可选优化)移除冗余的onSubmit包装函数,直接将handleSubmit绑定给表单提交事件即可

修复后的核心提交逻辑代码如下:

async function handleSubmit(e) {
  e.preventDefault();

  if (!emailRef.current.value) {
    return setError('Please enter an Email Address');
  }

  if (!passwordRef.current.value) {
    return setError('Please enter a password');
  }

  setLoading(true);
  setError('');

  try {
    const response = await fetch(
      `${process.env.REACT_APP_API_URL}auth/login`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify({
          Email: emailRef.current.value,
          Password: passwordRef.current.value,
        }),
      },
    )
    if (response.ok) {
      auth.signin(emailRef.current.value);
      return navigate('/Dashboard');
    }
    const errorText = await response.json();
    throw new Error(errorText.message);
  } catch (err) {
    setError(err.message);
  } finally {
    // 无论请求成功还是失败,最终都重置加载状态
    setLoading(false);
  }
}

对应的表单绑定可以直接简化为:

<form onSubmit={handleSubmit}>

用async/await+try/catch/finally的写法比原始Promise链式调用更直观,也能避免出现漏写回调、状态重置遗漏的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:39:19