Redux多Action派发异常:返回函数导致State变为undefined
咱们先把你的问题核心拆解开,再一步步分析原因和解决办法:
问题重现
你有两个Reducer写法,一个正常工作,一个导致State变为undefined:
出问题的写法:
const fetchSideBarData = (state, action) => { const request = action.sideBarData; console.log("KKKK"); return () => { fetchSideBarDataBegin(state); }; }
正常工作的写法:
const fetchSideBarData = (state, action) => { const request = action.sideBarData; console.log("KKKK"); return fetchSideBarDataBegin(state); }
原因解析
Redux的Reducer有个铁规则:它必须是纯函数,并且返回一个合法的State值(可以是对象、数组、基本类型,但不能是函数、Promise这类非序列化的值)。
第一种写法的问题就出在返回值上:你返回了一个匿名函数,而不是fetchSideBarDataBegin(state)执行后生成的新State。Redux会把这个函数当成新的State存储起来,但后续的状态读取、组件订阅都会因为State变成了函数而出现异常——函数不是合法的Redux State类型,最终就会导致你看到的State变为undefined的问题。
另外补充一点:fetchSideBarDataBegin如果是另一个Reducer函数,它的作用是接收State和Action返回新State,第二种写法里你直接调用它并返回结果,这符合Reducer的工作逻辑;但第一种写法把它包在函数里返回,完全偏离了Redux对Reducer的要求。
如何实现“派发多个Action”的需求
你想触发多个Action,但Reducer本身不能直接派发Action——它的职责只是根据Action更新State。要实现多Action派发,你需要用Redux中间件,比如redux-thunk,它允许你编写返回函数的Action创建器,在这个函数里可以多次调用dispatch来派发多个Action。
举个实际的例子:
// 1. 先定义Action类型和基础Action创建器 const FETCH_SIDEBAR_BEGIN = 'FETCH_SIDEBAR_BEGIN'; const FETCH_SIDEBAR_SUCCESS = 'FETCH_SIDEBAR_SUCCESS'; const fetchSideBarBegin = () => ({ type: FETCH_SIDEBAR_BEGIN }); const fetchSideBarSuccess = (data) => ({ type: FETCH_SIDEBAR_SUCCESS, payload: data }); // 2. 使用thunk编写能派发多个Action的逻辑 const fetchSideBarData = (sideBarData) => { return (dispatch) => { console.log("KKKK"); // 派发第一个Action dispatch(fetchSideBarBegin()); // 这里可以加入异步操作(比如API请求) // 完成后派发第二个Action dispatch(fetchSideBarSuccess(sideBarData)); }; };
然后你的Reducer只需要专注处理每个Action对应的状态更新:
const initialState = { loading: false, data: null }; const sidebarReducer = (state = initialState, action) => { switch(action.type) { case FETCH_SIDEBAR_BEGIN: return { ...state, loading: true }; case FETCH_SIDEBAR_SUCCESS: return { ...state, loading: false, data: action.payload }; default: return state; } };
这样既符合Redux的核心规则,又能实现你想要的“触发多个Action”的逻辑。
内容的提问来源于stack exchange,提问作者Shivam Sahil

