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

React-Redux同组件内loading状态重置异常问题求助

解决React-Redux中再次进入组件时Loading状态不更新的问题

这个问题的核心原因很清晰:你的loading状态只在数据获取成功后被设为false,但当你返回后再次进入组件时,没有任何操作把它重新设为true,所以reducer里的loading值一直停留在false,自然不会显示Spinner了。

下面是具体的修复步骤,我们通过在发起请求前更新loading状态来解决这个问题:

1. 添加新的Action Type

首先在你的types.js文件里新增一个用于标记加载开始的类型:

// 在types.js中添加
export const MOVIELIST_THEATER_LOADING = 'MOVIELIST_THEATER_LOADING';

2. 修改Action,发起请求前先更新Loading状态

更新fetchTheater方法,在调用fetch之前先dispatch一个action把loading设为true:

// action.js 修改后的fetchTheater
export const fetchTheater = ({ enCity }) => {
  return (dispatch) => {
    // 发起请求前,先标记为加载中
    dispatch({ type: MOVIELIST_THEATER_LOADING });
    fetch(`https://obscure-reaches-65656.herokuapp.com/api/drivers?city=${enCity}&lng=121.584065&lat=25.041317`)
      .then(response => response.json())
      .then(responseData => {
        console.log(responseData);
        dispatch({ type: MOVIELIST_THEATER, payload: responseData });
      })
      .catch((error) => {
        console.log(error);
        // 错误情况下也要把loading设为false,避免一直显示Spinner
        dispatch({ type: MOVIELIST_THEATER, payload: [] });
      });
  };
};

3. 更新Reducer,处理加载开始的Action

在MovieListReducer.js里新增对MOVIELIST_THEATER_LOADING的处理,把loading设为true:

// MovieListReducer.js 修改后的代码
import { 
  MOVIELIST_MAINACTIVITY, 
  MOVIELIST_THISWEEK, 
  MOVIELIST_THEATER, 
  MOVIELIST_TIME, 
  MOVIE_DETAIL,
  MOVIELIST_THEATER_LOADING // 导入新的type
} from '../actions/types';

const INITIAL_STATE = {
 mainMovie: [],
 thisWeek: [],
 theaterList: [],
 timeList: [],
 movieDetail: [],
 loading: true
};

export default (state = INITIAL_STATE, action) => {
 switch (action.type) {
 case MOVIELIST_MAINACTIVITY:
 return { ...state, mainMovie: action.payload };
 case MOVIELIST_THISWEEK:
 return { ...state, thisWeek: action.payload };
 case MOVIELIST_THEATER_LOADING: // 新增的case
 return { ...state, loading: true };
 case MOVIELIST_THEATER:
 return { ...state, theaterList: action.payload, loading: false };
 case MOVIELIST_TIME:
 return { ...state, timeList: action.payload };
 case MOVIE_DETAIL:
 return { ...state, movieDetail: action.payload };
 default:
 return state;
 }
};

为什么这样能解决问题?

现在每次进入TheaterList组件时,componentDidMount会调用fetchTheater,这个方法会先dispatchMOVIELIST_THEATER_LOADING把loading设为true,此时组件会渲染Spinner;当请求完成(无论成功或失败)后,再dispatchMOVIELIST_THEATER把loading设为false,同时更新数据,组件就会渲染FlatList了。

内容的提问来源于stack exchange,提问作者Morton

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:13:08