如何使用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
相关产品推荐
相关产品推荐

