React Redux reducer修改状态后组件未更新、应返回数组却返回空对象
问题核心原因
- Redux的reducer必须是纯函数,不允许包含异步逻辑、API调用、副作用操作,也不能用
async/await修饰,你当前给reducer加了async会导致返回的是Promise对象而非实际的状态值,Redux无法正确识别更新。 - 你用
combineReducers注册了名为reducer的切片,所以初始状态下store的结构是{ reducer: [] },但因为reducer是异步的,第一次返回的Promise被Redux处理异常,所以先显示成了空对象。 - 你在reducer里直接修改
state = result的写法也不符合纯函数要求,reducer必须返回新的状态副本,不能直接修改入参state。
解决方案
你需要把异步逻辑移到action creator里,配合Redux中间件(比如redux-thunk)来处理异步请求,步骤如下:
第一步:安装配置redux-thunk
npm install redux-thunk
修改store的创建代码,注入thunk中间件:
import { createStore, combineReducers, applyMiddleware } from 'redux' import thunk from 'redux-thunk' import { reducer } from '../reducer/reducer' const rootReducer = combineReducers({ reducer }) // thunk中间件支持异步action处理 const store = createStore(rootReducer, applyMiddleware(thunk)) export default store
第二步:修改reducer,移除所有异步逻辑
import { ADD_NOTE, ADD_SUBJECT, ADD_TOPIC, REMOVE_NOTE, REMOVE_SUBJECT, REMOVE_TOPIC, UPDATE_NOTE, UPDATE_SUBJECT, UPDATE_TOPIC, FETCH_ALL_DATA } from '../action/action-types' const initialState = [] export const reducer = (state = initialState, action) => { switch(action.type){ case FETCH_ALL_DATA: // 直接返回action携带的请求结果,生成新状态 return action.payload; default: return state } }
第三步:修改fetchAllData异步action实现
在你的../action/action.js文件中调整代码:
import { FETCH_ALL_DATA } from './action-types' import { fetchAllSubjects } from '../controller/fetchAllSubjects' // 异步action返回函数,thunk中间件会自动执行这个函数 export const fetchAllData = () => { return async (dispatch) => { const result = await fetchAllSubjects() // 请求拿到结果后再dispatch action通知reducer更新状态 dispatch({ type: FETCH_ALL_DATA, payload: result }) } }
第四步:可选优化组件取值逻辑
如果只需要reducer切片里的数组,可以直接修改mapStateToProps取对应字段:
const mapStateToProps = state => ({ data : state.reducer })
调整后组件输出的就是你预期的数组,不需要再额外取reducer属性。
内容的提问来源于stack exchange,提问作者Sushil Shinde
相关产品推荐
相关产品推荐

