【问题标题】:"Error: You may not call store.getState() while the reducer is executing."“错误:你不能在 reducer 执行时调用 store.getState()。”
【发布时间】:2019-01-01 08:18:38
【问题描述】:

我刚刚将功能齐全的 react-native 应用升级到 Redux v4,但现在我收到以下错误:

错误:错误:错误:错误:您不能在 reducer 执行时调用 store.getState()。 reducer 已经接收到状态作为参数。从顶部 reducer 向下传递,而不是从 store 中读取。

我怀疑问题是我在其他组件中有许多组件,每个组件都有自己的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]

【问题讨论】:

  • 可以添加堆栈跟踪吗?这将有助于我们给出更准确的答案。
  • 您能分享一下您实际调用store.getState() 的代码的sn-p 吗?
  • 我不调用 store.getState()
  • 如果我们能看到 SceneView.js:9 和 createTabNavigator.js:10 发生了什么会很有用
  • 这两个都不是我的代码。我不确定 SceneView 来自什么,但 createTabNavigator 来自 react-navigation github.com/react-navigation/react-navigation

标签: javascript reactjs redux react-redux


【解决方案1】:

注意:我使用的是 Saga

在我的例子中,我在 reducer 中添加了导航代码。

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

      RootNavigation.navigate('LoginOTPScreen');
    },

一开始它可以工作,但是当我在被调用的新屏幕中使用/访问状态时

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.”

原因

Reducer 应该是一个纯函数。它应该接受有效载荷并修改状态,仅此而已。其他东西被视为副作用。

在我的情况下,我加载了一个新组件,该组件也消耗 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
    ...

【讨论】:

    【解决方案2】:

    tl;博士

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

    纯还原剂

    Redux reducer 必须是纯的。这意味着它们不应该有副作用。副作用应该来自 thunks 或 sagas。在我的例子中,reducer 看起来像这样:

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

    history.push('/some-route'); 部分搞砸了状态管理。将其从 reducer 中移除并将其放置到在相同操作类型上调用的 saga 中解决了该问题:

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

    【讨论】:

      【解决方案3】:

      我在 Chrome 上遇到了这个问题。将我的 redux 版本从 4.0.2 降级到 3.7.2 为我修复了它。

      npm uninstall redux

      npm install redux@3.7.2

      【讨论】:

        【解决方案4】:

        就我而言,问题与开发扩展无关。我在使用深度链接时遇到了这个错误 - 正在更新减速器内的路由查询。在 settimeout 中封装与操作 url 相关的逻辑修复了错误。

        【讨论】:

          【解决方案5】:

          redux-devtools-extension新的 v2.16.0 版本存在问题。

          在我们等待修复时,这里有几个解决方法...

          1. 恢复到工作版本 v2.15.5(适用于 Chrome

          2. 或者只是暂时禁用你的redux-devtool扩展

            • 在浏览器级别或通过您的代码(您创建 redux 存储的位置)

          仅供参考:这并不能解决 OP 的问题,但确实解决了开发人员从 2018 年 11 月 27 日开始收到以下错误消息的问题。

          Error: You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store.


          更新

          v2.16.2 已经released

          对于之前禁用扩展的用户,只需重新启用它并将您的 redux 开发工具从 2.16.0 更新到 2.16.2 Update Redux Dev tools

          【讨论】:

          • 这个问题的好解决方法,实际上是在一个小时前为每个使用 redux-devtools-extension 的人弹出的,但并没有真正解决 OP 之前提出的问题这个错误的 v2.16.0 版本...只是说
          • @bitstrider 当然它没有解决 OP 的问题。但它确实似乎在帮助很多人解决当前的情况。对于那些想知道这个问题的状态的人,这里是为它发布的github issue
          • 今早让我省了很多头痛
          • 花了将近一个小时才找到这个问题。恢复到 v2.15.5。现在一切正常。
          • redux-devtools-extension 2.16.1 版本已经发布,修复了这个问题
          【解决方案6】:

          适合我的解决方案

          禁用 Redux 开发工具 的 Chrome 扩展。或从您的代码中删除 logger

          更新:将您的 redux 开发工具从 2.16.0 更新到 2.16.1 Update Redux Dev tools.

          【讨论】:

            【解决方案7】:

            现在应该修复了。将您的 redux 开发工具从 2.16.0 更新到 2.16.1

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

            【讨论】:

            • 我在 2.17.0 上仍然会发生这种情况
            【解决方案8】:

            这就是我所做的:刚刚从我的 store.js 文件中评论了 Chrome Redux Devtools Extension 的行。

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

            问题是在一小时前才开始的。众所周知,该扩展在开发过程中非常方便,所以让我们等待当局的真正修复。

            【讨论】:

              【解决方案9】:

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

              或者,如果您正在寻找临时解决方法(对于 chrome),您可以下载 https://github.com/zalmoxisus/redux-devtools-extension/releases/download/2.15.5/extension.zip,然后将其解压缩到某个文件夹。

              输入 chrome://extensions 并从左上角打开开发者模式,然后点击 Load Unpacked 并选择提取的文件夹以供使用。

              问题:https://github.com/reduxjs/redux-devtools/issues/413

              【讨论】:

                【解决方案10】:

                在我的项目中。这个问题总有一天突然冒出来的。

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

                所以遇到这种错误,你应该在几个浏览器中测试才能发现问题。

                【讨论】:

                  【解决方案11】:

                  我在使用聚合物 3 构建 PWA 时遇到了同样的错误。 store.js 还尝试使用我不得不停用的 redux 开发工具:

                  ...
                  // 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))
                  );
                  ...
                  

                  【讨论】:

                    【解决方案12】:

                    就我而言,我必须删除 composeWithDevTools - chrome 插件

                    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);
                    

                    【讨论】:

                    • 谢谢。这对我有用。禁用 Redux Chrome 扩展也可以。这只是从今天开始发生。想知道为什么...
                    • 同样的@JacobGoh,面临同样的问题,以前从未遇到过。 Chrome 网上商店说该扩展程序已于 11 月 27 日更新,也许他们破坏了一些东西。
                    • @ImanMahmoudinasab - 我使用的是 Chrome 版本 55.x(尽管最新版本是 70.x),但仍然面临同样的问题。卸载 Redux DevTools (v 2.16.0) 后,我的应用程序按照 Viet Le 的建议运行良好。
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-03-03
                    • 1970-01-01
                    • 2019-06-29
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多