【发布时间】:2021-03-11 21:22:39
【问题描述】:
我收到此错误:
Reducer "menu" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you dont want to set a value for this reducer, you can use null instead of undefined. 5 | import { rootReducer } from "./reducers/rootReducer"; 6 | > 7 | const reducers = combineReducers({ | ^ 8 | root: rootReducer, 9 | menu: menuReducer, 10 | searcher: searchReducer, at node_modules/redux/lib/redux.js:378:13 at Array.forEach (<anonymous>) at assertReducerShape (node_modules/redux/lib/redux.js:371:25) at combineReducers (node_modules/redux/lib/redux.js:436:5) at Object.<anonymous> (src/store/store.ts:7:18) at Object.<anonymous> (src/store/actionCreator.ts:1:1) at Object.<anonymous> (src/store/initialState.ts:5:1) at Object.<anonymous> (src/store/reducers/rootReducer.ts:1:1) at Object.<anonymous> (src/tests/rootReducer.test.ts:1:1) console.error node_modules/redux/lib/redux.js:325 No reducer provided for key "root" Test Suites: 1 failed, 1 total Tests: 0 total Snapshots: 0 total Time: 1.175s Ran all test suites related to changed files.
在测试这个 reducer (rootReducer.ts) 时:
import { rootInitialState, Reducer, action } from "../initialState";
class RootReducer implements Reducer {
private initialState: object;
public constructor(initialState: object) {
this.initialState = initialState;
}
private addNewText = (currentTexts: object, newText: object): object => {
let newTexts: object = { ...currentTexts };
newTexts[newText["name"]] = newText["text"];
return newTexts;
};
private switchBodyScroll = (
payload: "LOCK" | "UNLOCK"
): "LOCKED" | "UNLOCKED" => {
if (payload === "LOCK") {
document.getElementsByTagName("body")[0].classList.add("scroll-lock");
return "LOCKED";
} else {
document.getElementsByTagName("body")[0].classList.remove("scroll-lock");
return "UNLOCKED";
}
};
public reduce = (
state: object = this.initialState,
action: action
): object => {
if (action.type === "SWITCH_BODY_SCROLL") {
return {
...state,
bodyScrollState: this.switchBodyScroll(action.payload),
};
} else if (action.type === "SWITCH_MINIMAP_MODE") {
return {
...state,
minimap: {
...state["minimap"],
mode: action.payload.minimapClassList,
buttonClassList: action.payload.buttonClassList,
},
};
} else if (action.type === "SET_THEMES") {
return { ...state, themes: [action.payload.items] };
} else if (action.type === "SET_CURRENT_PAGE") {
return {
...state,
currentPageId: action.payload.id,
nextPage: action.payload.next,
currentPage: [...action.payload.components],
};
} else if (action.type === "ADD_NEW_TEXT") {
return {
...state,
texts: { ...this.addNewText(state["text"], action.payload) },
};
} else if (action.type === "SET_PAGE_SEARCHER_VALUE") {
return { ...state, pageSearcherValue: action.payload };
} else {
return state;
}
};
}
export const rootReducer = new RootReducer(rootInitialState).reduce;
例如,menuReducer.ts。它包含默认状态,但无论如何返回未定义:
import { menuInitialState, Reducer, action } from "../initialState";
class MenuReducer implements Reducer {
private initialState: object;
public constructor(initialState: object) {
this.initialState = initialState;
}
public reduce = (
state: object = this.initialState,
action: action
): object => {
if (action.type === "SWITCH_MENU_MODE") {
return { ...state, compactMenuCurtain: action.payload };
} else {
return state;
}
};
}
export const menuReducer = new MenuReducer(menuInitialState).reduce;
使用此测试 (rootReducer.test.ts):
import { rootReducer } from "../store/reducers/rootReducer";
it("rootReducer should return LOCKED with payload LOCK", () => {
expect(
rootReducer(undefined, { type: "SWITCH_BODY_SCROLL", payload: "LOCK" })
).toBe("LOCKED");
});
store.ts 文件如下所示:
import { combineReducers, createStore } from "redux";
import { menuReducer } from "./reducers/menuReducer";
import { searchReducer } from "./reducers/searchReducer";
import { rootReducer } from "./reducers/rootReducer";
const reducers = combineReducers({
root: rootReducer,
menu: menuReducer,
searcher: searchReducer,
});
export const store = createStore(reducers);
我尝试对其他减速器进行相同的测试。我得到了类似的错误。 当然,我已经检查了菜单减速器并尝试测试其他类似的减速器。我得到类似的错误。此外,如果没有给出,每个减速器都将初始状态设置为默认值。我的应用程序在浏览器中运行没有任何错误,我只有通过测试才能得到。任何导入的东西都是 .ts 文件。也许,我只是错过了一些东西 - 现在我正在学习开玩笑。
即使我只是将减速器写入控制台或获取此类型(menuReducer.test.ts),我也会遇到相同的错误:
import { menuReducer } from "../store/reducers/menuReducer";
it("rootReducer should return LOCKED with payload LOCK", () => {
console.log(menuReducer);
console.log(typeof menuReducer); // That's a method of class
});
【问题讨论】:
-
当然,我已经检查了菜单缩减程序,如果没有给出默认设置,那么我已经将初始状态设置为默认值 - 那么请让其他人也这样做。 stackoverflow.com/help/mcve 是代码相关问题所必需的。
标签: reactjs testing redux jestjs