“错误: 在执行 rereduce 时不能调用 store.getState()。”

我刚刚将我的全功能本机应用程序升级到了 Redux v4,但是现在我得到了以下错误:

Error: Error: Error: Error: 在执行 reduce 时不能调用 store.getState ()。减法器已经接收了状态作为参数。从最上面的减速器传下来,而不是从商店里读。

我怀疑问题在于我在其他组件中有许多组件,每个组件都有自己的 connect(mapStateToProps, mapDispatchToProps)(Component),我认为这不是实现它的正确方法,尽管我不确定实现它的正确方法。

任何方向都非常感谢!

堆栈追踪:

    This error is located at:
in Connect(SideBarApp) (at SceneView.js:9)
in SceneView (at createTabNavigator.js:10)
in RCTView (at View.js:43)
in RCTView (at View.js:43)
in ResourceSavingScene (at createBottomTabNavigator.js:86)
in RCTView (at View.js:43)
in RCTView (at View.js:43)
in TabNavigationView (at createTabNavigator.js:127)
in NavigationView (at createNavigator.js:59)
in Navigator (at createNavigationContainer.js:376)
in NavigationContainer (at SceneView.js:9)
in SceneView (at SwitchView.js:12)
in SwitchView (at createNavigator.js:59)
in Navigator (at createNavigationContainer.js:376)
in NavigationContainer (at AppNavigator.js:36)
in App (created by Connect(App))
in Connect(App) (at index.ios.js:23)
in Provider (at index.ios.js:22)
in TheNewsApp (at renderApplication.js:32)
in RCTView (at View.js:43)
in RCTView (at View.js:43)
in AppContainer (at renderApplication.js:31)


This error is located at:
in NavigationContainer (at SceneView.js:9)
in SceneView (at SwitchView.js:12)
in SwitchView (at createNavigator.js:59)
in Navigator (at createNavigationContainer.js:376)
in NavigationContainer (at AppNavigator.js:36)
in App (created by Connect(App))
in Connect(App) (at index.ios.js:23)
in Provider (at index.ios.js:22)
in TheNewsApp (at renderApplication.js:32)
in RCTView (at View.js:43)
in RCTView (at View.js:43)
in AppContainer (at renderApplication.js:31)


This error is located at:
in NavigationContainer (at AppNavigator.js:36)
in App (created by Connect(App))
in Connect(App) (at index.ios.js:23)
in Provider (at index.ios.js:22)
in TheNewsApp (at renderApplication.js:32)
in RCTView (at View.js:43)
in RCTView (at View.js:43)
in AppContainer (at renderApplication.js:31)
getState@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:79579:24
runComponentSelector@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:78896:56
initSelector@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:79019:28
Connect(SideBarApp)@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:78969:29
constructClassInstance@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:20826:32
updateClassComponent@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:22393:35
performUnitOfWork@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:24922:27
workLoop@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:24955:47
renderRoot@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:24988:21
performWorkOnRoot@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:25549:23
performWork@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:25481:30
performSyncWork@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:25456:20
requestWork@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:25362:26
scheduleWork@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:25224:28
enqueueSetState@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:20681:23
setState@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:2380:37
dispatch@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:80901:27
navigate@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:80517:24
nav@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:80470:44
combination@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:79810:38
dispatch@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:79628:38
setLoginStatus@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:112247:19
http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:112199:44
tryCallOne@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:8818:16
http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:8919:27
_callTimer@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:8162:17
_callImmediatesPass@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:8198:19
callImmediates@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:8417:33
__callImmediates@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:7741:32
http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:7580:34
__guard@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:7721:15
flushedQueue@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:7579:21
flushedQueue@[native code]
invokeCallbackAndReturnFlushedQueue@[native code]
29586 次浏览

在我的情况下,我必须删除 ComposWithDevTools-一个铬插件

import { createStore, combineReducers, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';


// const enhancer = composeWithDevTools(applyMiddleware(thunk))
const enhancer = applyMiddleware(thunk)


const store = createStore(reducers, enhancer);

我用聚合物3做的 PWA 也有同样的错误。 Js 还尝试使用 redux dev 工具,我不得不停用它:

...
// Sets up a Chrome extension for time travel debugging.
// See https://github.com/zalmoxisus/redux-devtools-extension for more information.
//const devCompose = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const devCompose =  compose;


// Initializes the Redux store with a lazyReducerEnhancer (so that you can
// lazily add reducers after the store has been created) and redux-thunk (so
// that you can dispatch async actions). See the "Redux and state management"
// section of the wiki for more details:
// https://github.com/Polymer/pwa-starter-kit/wiki/4.-Redux-and-state-management
export const store = createStore(
state => state,
devCompose(
lazyReducerEnhancer(combineReducers),
applyMiddleware(thunk))
);
...

这是 Redux-devtools-扩展新的2.16.0版本的问题。

在我们等待修复的时候,这里有一些 解决办法

  1. 返回 到工作版本 v2.15.5(为了 Chrome)

  2. 或者只是简单的 关闭你的 Redux-devtool 扩展现在。

    • 无论是在浏览器级别还是通过代码(在其中创建 redux 存储)

FYI : 这并没有解决 OP 的问题,但是解决了开发人员从11/27/18开始收到以下错误消息的问题。

错误: 在执行 reduce 时不能调用 store.getState ()。减法器已经接收了状态作为参数。从最上面的减速器传下来,而不是从商店里读。


更新

V2.16.2 已经发布

对于那些之前禁用了该扩展的用户,只需重新启用它并将 redux dev 工具从2.16.0更新到2.16.2 更新 Redux Dev 工具

在我的项目中,这个问题总有一天会突然出现。

我的解决方案: < strong > 禁用 Chrome 扩展-Redux Devtools。 然后一切就恢复正常了。

因此,对于这种错误,您应该在多个浏览器中进行测试,以找到问题所在。

我是这样做的: 刚刚在 store.js 文件中为 Chrome Redux Devtools 扩展添加了注释。

....


const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware)
///This line--> window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);


....

问题一小时前才刚刚开始。正如我们所知道的那样,扩展在开发过程中非常方便,所以让我们等待权威机构的真正修复。

禁用 chrome 扩展或从代码中删除 composeWithDevTool可以快速修复。但是我们都知道,我们需要扩展来跟踪应用程序状态并正确地管理它。所以我今天创建了一个问题,请支持希望,有人从 redux 团队会给我们回来。

或者,如果你正在寻找一个临时的解决方案(为铬) ,你可以下载 https://github.com/zalmoxisus/redux-devtools-extension/releases/download/2.15.5/extension.zip,然后解压缩到一些文件夹。

键入 chrome://扩展,从左上角打开开发人员模式,然后单击 Load Unpack 并选择要使用的提取文件夹。

发行: https://github.com/reduxjs/redux-devtools/issues/413

解决方案,为我工作

禁用浏览器扩展 Redux Dev 工具。或从代码中删除 伐木工

Update : 将 redux dev 工具从2.16.0更新到2.16.1 更新 Redux Dev 工具

现在应该修复了。将 redux dev 工具从2.16.0更新到2.16.1

Https://github.com/zalmoxisus/redux-devtools-extension/issues/588#issuecomment-442396540

在我的案例中,这个问题与开发扩展无关。我遇到了这个错误,当工作与深度链接-是更新路由查询内减速器。与在 settimeout 中操作 URL 相关的包装逻辑修复了错误。

我在 Chrome 上遇到了这个问题,我把 redux 的版本从4.0.2降级到了3.7.2,解决了这个问题。

npm uninstall redux

npm install redux@3.7.2

博士

确保您没有任何代码,导致副作用在您的减速器!

纯粹的还原剂

还原剂必须是纯的。这意味着它们不应该有副作用。副作用应该出现在传奇故事里。在我的例子中,减速器看起来是这样的:

case REDIRECT_ON_EVENT: {
history.push('/some-route'); // side effect: redirection
return {
...state,
path: action.payload.path,
};
}

history.push('/some-route');部分搞砸了状态管理。将它从减速器中移除,并将其放置到一个长篇故事中,该长篇故事被调用于相同的动作类型,从而解决了这个问题:

function redirectToSomeRoute() {
history.push('/some-route');
}


takeEvery(REDIRECT_ON_EVENT, redirectToSomeRoute),

注意 : 我正在使用 Saga

在我的例子中,我在减速器中添加了一个导航代码。

    sendOTPSuccess: (state, action) => {
state.wip = false;


RootNavigation.navigate('LoginOTPScreen');
},

一开始它是工作的,但是当我使用/访问被称为 new Screen 的内部状态时

import { useDispatch, useSelector } from "react-redux";
import * as sessionActions from "../../models/session";


const LoginOTP: () => Node = (props) => {
const session = useSelector(sessionActions.selectSession);
const dispatch = useDispatch();
...

出现了错误。

“Error: You may not call store.getState() while the reducer is executing.”

因为

减缩器应该是一个纯函数。它应该接受一个有效载荷并修改状态,而不是其他任何东西。其他一些东西被认为是副作用。

我的情况下,我加载了一个新的组件,也使用 state数据和状态修改尚未完成。这就是问题的根源。

解决方案

我只是将导航移动到相应的 saga

// worker Saga:
function* sendOTPSaga({ payload }) {
const { phoneNumber } = payload;
try {
const response = yield call(Api.sendOtp, { phoneNumber });
if (response.status == 200) {
yield put(sessionActions.sendOTPSuccess(response.data));
RootNavigation.navigate('LoginOTPScreen'); // <---- Here
...