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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 06:27:04