使用combineReducers时报Reducer "loading"初始化返回undefined问题
问题解决方法
错误根因
combineReducers 初始化阶段会向所有传入的子reducer发送初始化动作,此时传入的state值为undefined,Redux要求所有reducer在这种场景下必须返回合法的初始状态,不能返回undefined。你当前的errorReducer和loadingReducer都没有处理state为undefined的场景,也没有设置默认初始值,因此触发了这个报错。
修复方案
1. 改造errorReducer.ts
给reducer添加初始状态,同时给state参数设置默认值,处理初始化场景,同时适配TS泛型要求:
import type { PayloadAction, SerializedError } from '@reduxjs/toolkit'; // 定义reducer初始状态 const initialState = { errors: {} as Record<string, unknown> }; // 给state参数加默认值,undefined时自动使用initialState export default <TState = {}>(state: TState & { errors: Record<string, unknown> } = initialState as TState & { errors: Record<string, unknown> }, action: PayloadAction) => { const { type, payload } = action; const matches = /\[(.*)]\s(TRIGGER|REQUEST|FAILURE)([_\w]+)*/.exec(type); if (!matches) return state; const [, stateKey, requestState, extra] = matches; const storageKey = extra ? `${stateKey}-${extra.substr(1).toLowerCase()}` : stateKey; return { ...state, errors: { ...state.errors, [storageKey]: requestState === 'FAILURE' ? payload : null, }, }; };
2. 同步改造loadingReducer.ts
逻辑和errorReducer完全一致,仅需把初始状态中的errors字段替换为loading,对应修改返回逻辑里的字段名即可,示例参考:
// loadingReducer.ts 核心修改部分 const initialState = { loading: {} as Record<string, boolean> }; export default <TState = {}>(state: TState & { loading: Record<string, boolean> } = initialState as TState & { loading: Record<string, boolean> }, action: PayloadAction) => { // 原有逻辑保持不变,仅修改返回对象里的字段为loading即可 }
验证
修改完成后重新运行项目,两个reducer初始化时会自动返回合法的初始状态,不会再触发undefined报错,原有逻辑无需调整可以正常使用。
内容的提问来源于stack exchange,提问作者perrer
相关产品推荐
相关产品推荐

