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

如何结合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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 16:05:28