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

React+Amplify Auth中点击按钮触发异步函数时加载指示器延迟问题

登录按钮加载状态延迟显示问题解决方案

问题场景

我有一个带受控输入的登录组件,还有一个可通过isLoading props切换按钮/加载器的Button组件。点击按钮会调用异步登录函数signIn,isLoading状态放在登录组件里并传递给Button。预期点击按钮后立即显示加载器,但实际存在延迟,推测是signIn的预检请求或async函数执行顺序导致React先处理await逻辑再更新状态。

相关代码

LoginForm.js

import { useState } from "react";
import "./Blog.css";
import Button from "../../UI/Button/Button";
import { signIn } from "aws-amplify/auth";

const LoginForm = props => {
    const [isLoading, setIsLoading] = useState(false);

    const handleFetchData = async (e) => {
        e.preventDefault();
        setIsLoading(true);
        const result = await signIn({username: "user@example.com", password: "passWor1"});
        setIsLoading(false);
        console.log(result);
    }

    return (
        <div className="container">
            <Button text="Submit" isLoading={isLoading} action={(e) => handleFetchData(e)}/>
        </div>
    )
}

export default LoginForm;

Button.js

import Loader from "../Loader/Loader";
import styles from "./Button.module.css";

const Button = ({action, color="blue", text="Submit", isLoading=false}) => {

    return (
        <>
            {isLoading? <Loader withImage={false} margin="22px auto 12px auto" /> :
            <button className={[styles.button, styles[color]].join(" ")} type="button"
            onClick={(e) =>{
                e.target.blur();
                action(e)
            }} >{text}</button>}
        </>
    )
}

export default Button;

问题原因

React的状态更新是异步且批量处理的,在同一个同步代码块中调用setIsLoading(true)后,React不会立即更新DOM,而是优先执行后续的await signIn逻辑(包括signIn内部的同步初始化、预检请求的前置准备工作),等这部分同步代码执行完毕后,才会处理状态更新并渲染加载器,因此出现了延迟。

解决方案

在setIsLoading(true)之后添加await Promise.resolve(),让React有机会先完成状态更新和DOM渲染,再执行signIn异步操作。同时为了避免登录失败后加载状态一直锁定,建议用try/catch/finally包裹异步逻辑:

修改后的handleFetchData函数:

const handleFetchData = async (e) => {
    e.preventDefault();
    setIsLoading(true);
    // 让React优先处理状态更新与DOM渲染
    await Promise.resolve();
    try {
        const result = await signIn({username: "user@example.com", password: "passWor1"});
        console.log(result);
    } catch (err) {
        // 处理登录错误
        console.error("登录失败:", err);
    } finally {
        // 无论成功失败都重置加载状态
        setIsLoading(false);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:04:55