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

React全局加载遮罩未正常工作的原因排查与解决请求

解决方案:全局加载状态异常问题

问题核心原因

你的代码中startLoading和stopLoading直接引用了当前渲染周期的loading状态快照,由于React的useState是异步更新,当多个请求并发触发状态更新时,会因为闭包陷阱导致状态更新丢失或不准确,最终出现数组为空但加载组件仍显示的情况。

修复方案

使用React的函数式状态更新替代直接依赖当前状态,确保每次状态更新都基于最新的状态值:

修改后的LoadingContext.jsx

'use strict';

import React, {
    createContext,
    useContext,
    useState,
} from 'react';

const LoadingContext = createContext({
    startLoading: (id) => {},
    stopLoading: (id) => {},
    isLoading: false,
});


export const useLoading = () => useContext(LoadingContext);

export const LoadingProvider = ({ children }) => {

    const [loading, setLoading] = useState([]);

    const startLoading = (id) => {
        // 函数式更新,基于最新状态添加ID,同时避免重复添加
        setLoading(prevLoading => {
            if (!prevLoading.includes(id)) {
                return [...prevLoading, id];
            }
            return prevLoading;
        });
    };

    const stopLoading = (id) => {
        // 函数式更新,基于最新状态过滤掉目标ID
        setLoading(prevLoading => prevLoading.filter(item => item !== id));
    };

    return (
        <LoadingContext.Provider value={{
            startLoading,
            stopLoading,
            isLoading: loading.length > 0,
        }}>
            {children}
        </LoadingContext.Provider>
    );
}

额外优化建议

  • 请求ID唯一性:确保每个请求的ID唯一,比如在并发请求时,可以给ID添加时间戳或者随机后缀,避免不同请求使用相同ID导致的状态混乱。
  • 异常兜底:你的代码已经用finally包裹stopLoading,能确保无论请求成功或失败都会终止加载状态,这部分无需修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 01:03:31