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
相关产品推荐
相关产品推荐

