如何结合Redux Toolkit使用React Suspense实现加载状态?
解决Redux Toolkit异步请求时加载状态不显示的问题
你用React Suspense没生效是因为Suspense并不是用来处理普通Redux异步请求的。它的设计目标是捕获组件树中抛出的Promise(比如React.lazy懒加载组件、支持Suspense的数据源),而你当前的代码是在useEffect里dispatch异步action,组件本身并没有抛出Promise,所以Suspense根本感知不到加载状态。
下面是正确的实现方案:
步骤1:确保Redux Slice维护加载状态
你的getInformationCity应该是用createAsyncThunk创建的异步action,对应的slice需要通过extraReducers监听请求的pending/fulfilled/rejected状态,维护loading字段:
// informationCitySlice.js import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; export const getInformationCity = createAsyncThunk( 'informationCity/getData', async (cityId) => { // 替换为你的API请求逻辑 const response = await fetch(`your-api-url/${cityId}`); return response.json(); } ); const informationCitySlice = createSlice({ name: 'informationCity', initialState: { dataInformation: [], loading: false, error: null }, extraReducers: (builder) => { builder .addCase(getInformationCity.pending, (state) => { state.loading = true; state.error = null; }) .addCase(getInformationCity.fulfilled, (state, action) => { state.loading = false; state.dataInformation = action.payload; }) .addCase(getInformationCity.rejected, (state, action) => { state.loading = false; state.error = action.error.message; }); } }); export default informationCitySlice.reducer;
步骤2:修改组件,通过loading状态条件渲染
去掉Suspense,从Redux中读取loading状态,根据状态显示加载提示、错误信息或城市数据:
import React, { useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { getInformationCity } from "../informationCity/informationCitySlice"; export const InformationCity = () => { const dispatch = useDispatch(); const selectedCity = useSelector((state) => state?.cities?.selectedCity); const informacoes = useSelector( (state) => state?.informationCity?.dataInformation ); // 获取加载状态和错误信息 const loading = useSelector((state) => state?.informationCity?.loading); const error = useSelector((state) => state?.informationCity?.error); useEffect(() => { // 避免selectedCity为空时触发无效请求 if (selectedCity) { dispatch(getInformationCity(selectedCity)); } }, [dispatch, selectedCity]); // 加载中显示提示 if (loading) { return <div>加载数据中...</div>; } // 错误状态显示错误信息 if (error) { return <div>加载失败:{error}</div>; } // 数据为空时的提示(可选) if (!informacoes || informacoes.length === 0) { return <div>暂无城市数据</div>; } // 正常渲染城市列表 return ( <div> {informacoes.map((item) => ( <li key={item.id}> {/* 用数据唯一标识做key,不要用索引 */} City ID: {item.id} <br /> City Name: {item.nome} <br /> </li> ))} </div> ); };
补充说明
- 若想使用Suspense处理数据加载,需要使用支持Suspense的数据源(比如React Query的suspense选项、Relay),但Redux Toolkit的
createAsyncThunk目前不支持该模式,直接通过状态判断是更成熟的方案。 - 列表项的key尽量使用数据的唯一标识(如
item.id),而非数组索引,这样能提升React列表渲染的效率。
内容的提问来源于stack exchange,提问作者Begginer
相关产品推荐
相关产品推荐

