我用react redux制作了一个tic tac toe游戏。
我正在使用create-react-app。
我有以下商店:
import {createStore, combineReducers} from 'redux';
import gameSettingsReducer from './reducers/gameSettings.js';
import gameStatusReducer from './reducers/gameStatus.js';
const rootReducer = combineReducers({gameSettings: gameSettingsReducer,
gameStatus: gameStatusReducer});
export const defaultGameStatus = {
currentPlayerSymbol: "X",
turnNumber: 0,
currentView: "start-menu", //one of "start-menu", "in-game", "game-over"
winner: "draw", //one of "X", "O", "draw"
board: [["E", "E", "E"],
["E", "E", "E"],
["E", "E", "E"]],
lastMove: []
};
const store = createStore(rootReducer, {
gameSettings:{
playerSymbol: "X", //one of "X", "O"
difficulty: "easy" //one of "easy", "hard"
},
gameStatus: defaultGameStatus
});
export default store;
一切都按照我的预期运行。除了我运行测试(npm test
)时,控制台中会出现以下内容:
console.error node_modules\redux\lib\utils\warning.js:14
No reducer provided for key "gameStatus"
console.error node_modules\redux\lib\utils\warning.js:14
Unexpected key "gameStatus" found in preloadedState argument passed to createStore. Expected to find one of the known reducer keys instead: "gameSettings". Unexpected keys will be ignored.
在我的几个测试中,我甚至没有测试商店。所以我想在编译代码时会出现这种情况。
我尝试将console.log(gameStatusReducer)
放在根减速器行之前。
它表明gameStatusReducer未定义。
由于gameSettingsReducer和gameStatusReducer都以非常相似的方式创建,我不知道这个错误来自何处,甚至不知道如何进一步调查此问题。这仅在运行测试时显示。运行应用程序不会显示此问题,应用程序按预期工作。
所以,问题是:
答案 0 :(得分:14)
经过大量的敲击键盘后,我发现了一些线索。
快速解决方法为export
而不是gameStateReducer
制作正常default
,并使用import { gameStateReducer } from // ...
将其导入其他位置。
Jest会对某些导入进行自动模拟,显然在这种情况下会出现问题,或者它需要react-create-app
未提供的某种配置。
至于为什么Jest甚至记录了这个错误(考虑到相关代码没有在任何测试中导入),我想这是由于它的内部工作原理。
支持这一点有以下证据:向--testPathPattern
脚本添加npm test
标记仅匹配以.test.js
结尾的文件不会改变行为,但仍会出现错误。
如何调查问题:我首先弄清楚导致错误日志的代码是否在测试中(间接可能是这样,例如import
)。在排除这一点之后,我开始模拟传递给combineReducers
的函数,以确保任何更改都会影响错误日志的结果,并且确实如此。只需添加:
gameStatus: gameStatusReducer || (() => ())
...已经解决了这个问题,这意味着import
以及Jest / babel-jest
如何处理它是错误的。
如果我要进一步调查此问题,我会使用Jest创建自己的安装并提供我自己的配置,以查看Jest是否仍然编译整个应用程序。如果使用react-create-app
,将配置选项传递给Jest似乎并非易事。
答案 1 :(得分:10)
也有此错误,但使用的是TypeScript。
为了论证,我们说错误是No reducer provided for key "favourites"
。
对于导致此错误的测试,我们从该reducer的文件中导入了一个接口,该接口显然会运行该文件以生成导出。
我们的favourites
reducer导入我们的Redux存储,以查询该状态的另一部分,作为其一个切换案例的一部分。
出于某种原因,评论我们访问Store.getState().someOtherReducersState
的行会导致错误消失。
因此修复只是在测试文件中jest.mock('../route/to/Store');
导致错误输出。
答案 2 :(得分:0)
我也有此错误,原因与上面的评论相同,但我以更明智的方式解决了该问题:
将模块文件分成两个文件,一个用于减速器,一个用于动作(而不是包含两个文件)
答案 3 :(得分:0)
就我而言,事实证明其中一个模块存在循环依赖(它导入了整个 state
)
答案 4 :(得分:-3)
组合reducer,确保import VoxImplant from 'react-native-voximplant';
而不是juste将它们合并到一个对象中并将其提供给createStore。
例如:
import { combineReducers } from 'redux';