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

如何使用RTK Query通过中间件实现通用loader的统一处理

RTK Query 全局请求加载器实现方案

以下是两种可直接落地的实现方案,均满足「任意请求pending时展示加载器,请求结束(成功/失败)立即隐藏」的需求:

方案1:内置选择器实现(推荐,Redux Toolkit 1.9+ 支持)

RTK Query 官方已经内置了全局请求状态统计能力,无需自行维护状态:

  • 首先从你定义的Api实例中导出工具方法
// 你的api定义文件,比如src/services/api.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

export const api = createApi({
  reducerPath: 'api',
  baseQuery: fetchBaseQuery({ baseUrl: '/your-api-base' }),
  endpoints: () => ({}),
})

// 导出全局pending状态选择器
export const selectIsAnyRequestPending = api.util.selectIsAnyActionPending
  • 在全局加载器组件中订阅状态即可
import { useSelector } from 'react-redux'
import { selectIsAnyRequestPending } from '@/services/api'

const GlobalLoader = () => {
  const isLoading = useSelector(selectIsAnyRequestPending)
  return isLoading ? <div className="fixed top-0 left-0 w-full h-1 bg-blue-500"/> : null
}
export default GlobalLoader

方案2:自定义Slice兼容低版本

如果使用的Redux Toolkit版本低于1.9,可以自行监听请求动作维护计数:

  • 新增全局Loading状态Slice
// src/store/globalLoadingSlice.js
import { createSlice } from '@reduxjs/toolkit'
import { api } from '@/services/api'

const loadingSlice = createSlice({
  name: 'globalLoading',
  initialState: { pendingCount: 0 },
  extraReducers: (builder) => {
    builder
      .addMatcher(api.endpoints.matchPending, (state) => {
        state.pendingCount += 1
      })
      .addMatcher(api.endpoints.matchFulfilled, (state) => {
        state.pendingCount = Math.max(0, state.pendingCount - 1)
      })
      .addMatcher(api.endpoints.matchRejected, (state) => {
        state.pendingCount = Math.max(0, state.pendingCount - 1)
      })
  }
})

export const selectGlobalLoading = (state) => state.globalLoading.pendingCount > 0
export default loadingSlice.reducer
  • 将上述Slice的reducer注册到全局Store中
  • 加载器组件订阅selectGlobalLoading状态即可,效果和内置方案完全一致

可选优化:过滤不需要统计的请求

如果部分请求(如后台轮询、防抖搜索)不需要触发全局加载器,可以在请求时加自定义标记过滤:

// 发起请求时添加跳过标记
useSearchQuery(keyword, { extra: { skipGlobalLoading: true } })

// 在对应的matcher中增加判断
.addMatcher(api.endpoints.matchPending, (state, action) => {
  if (action.meta.arg.extra?.skipGlobalLoading) return
  state.pendingCount += 1
})
// fulfilled、rejected的matcher也要增加相同判断,避免计数错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 02:36:03