ReactJS中如何在Redux store的slice为空时展示加载器
Redux 配合 React 展示接口加载器的正确方案
核心说明
不要仅通过判断slice数据是否为空来展示加载器:空数据可能是接口正常返回的结果,也可能是请求报错后的状态,无法和「正在加载」的场景做区分。
实现步骤
1. 改造 Redux Slice,增加请求状态标识
推荐使用@reduxjs/toolkit的createAsyncThunk处理异步请求,自动生成请求的pending/fulfilled/rejected三个状态,在slice中存储对应状态:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit' // 定义多接口并发请求的thunk export const fetchAllRequiredData = createAsyncThunk( 'yourSliceName/fetchAllRequiredData', async () => { // 并发拉取所有需要的API数据 const [apiResult1, apiResult2, apiResult3] = await Promise.all([ fetch('/api/first').then(res => res.json()), fetch('/api/second').then(res => res.json()), fetch('/api/third').then(res => res.json()) ]) return { apiResult1, apiResult2, apiResult3 } } ) // 初始化state新增status和error字段 const initialState = { data: {}, status: 'idle', // 枚举值:idle(未请求)/loading(加载中)/succeeded(请求成功)/failed(请求失败) error: null } const yourDataSlice = createSlice({ name: 'yourSliceName', initialState, reducers: {}, extraReducers: builder => { builder // 请求开始时标记加载中 .addCase(fetchAllRequiredData.pending, state => { state.status = 'loading' }) // 请求成功时存储数据,标记加载完成 .addCase(fetchAllRequiredData.fulfilled, (state, action) => { state.status = 'succeeded' state.data = action.payload }) // 请求失败时存储错误信息,标记请求失败 .addCase(fetchAllRequiredData.rejected, (state, action) => { state.status = 'failed' state.error = action.error.message }) } }) export default yourDataSlice.reducer
2. React 组件中根据状态渲染加载器
在业务组件中通过useSelector获取slice的状态,根据状态判断是否展示加载器:
import { useEffect } from 'react' import { useSelector, useDispatch } from 'react-redux' import { fetchAllRequiredData } from './yourDataSlice' // 自定义的加载动画组件,可替换为你项目中的加载组件 import PageLoader from './components/PageLoader' function YourBusinessPage() { const dispatch = useDispatch() // 从Redux store中取对应slice的状态和数据 const { status, data, error } = useSelector(state => state.yourSliceName) // 页面首次加载时触发数据请求 useEffect(() => { if (status === 'idle') { dispatch(fetchAllRequiredData()) } }, [status, dispatch]) // 加载中状态直接返回加载器 if (status === 'loading') { return <PageLoader /> } // 请求失败状态展示错误提示 if (status === 'failed') { return <div className="error-tip">数据加载失败:{error}</div> } // 加载完成后正常渲染业务内容,即使data为空也会展示空状态而不是一直显示加载器 return ( <div className="business-content"> {/* 你的业务渲染逻辑 */} </div> ) } export default YourBusinessPage
细粒度控制方案
如果需要给不同接口的内容单独展示加载器,可以在slice中给每个接口单独配置对应的status字段,请求时单独更新对应接口的状态即可,不需要使用setTimeout做假加载判断。
内容的提问来源于stack exchange,提问作者FARKADI06
相关产品推荐
相关产品推荐

