【问题标题】:Stack overflow when hot reloading a reducer with React Native and Redux使用 React Native 和 Redux 热重新加载减速器时堆栈溢出
【发布时间】:2016-08-20 09:10:41
【问题描述】:

我将 Redux 与 React Native 和 HMR 一起使用。当我更改减速器时,接受会冒泡到我的 configureStore.js 文件,该文件调用它:

if (module.hot) {
    module.hot.accept(() => {
        const nextRootReducer = require('../reducers/index').default;
        store.replaceReducer(nextRootReducer);
    });
}

然后 HMR 继续循环搜索引用,直到堆栈溢出。 会不会是某个地方有循环引用?如果是这样,任何追踪它的提示?我尝试单步执行require.js 代码,但“引用”保留为数字,因此很难找到正确的文件。

【问题讨论】:

  • 我也有类似的问题。对我来说,最初的 store 对象变得未定义,当您直接使用 store 时,这 - 虽然不是惯用的 - 是一个问题。起初,这是唯一的问题,但随着时间的推移,当我更新减速器时,它会一起崩溃(红屏死机)。我假设这来自添加诸如redux-storage 或其他一些中间件之类的包。更新动作更是一个问题——那些从来没有很好地工作过。我的假设是我需要在传递给module.hot.accept 的函数中做更多事情。 IE。重做我最初在configureStore 中所做的一切。
  • 更新:你的问题让我再次思考这个问题,我终于解决了,哈哈。不确定它是否适用于你,但我做了两件事:我做了我假设的事情,我没有用 redux 存储正确地重新配置存储,所以我这样做了。 IE。我确保所有之前设置减速器的步骤都在module.hot.accept 中再次完成。然后就操作而言,我停止将它们导入我的configureStore 文件,因为我没有使用它们——这解决了更改我的操作文件破坏了存储的问题,它无法正确“接受”变化。

标签: javascript react-native redux hot-module-replacement


【解决方案1】:

如果你想检查它,这是我的确切代码:

export default function configureStore() {
  engine = createEngine('appstate');
  engine = filter(engine, null, ['appStateLoaded', 'appReady', 'tourReady', 'tourPage', 'tooltipStep', 'connected']);
  const cacheState = storage.createMiddleware(engine); //OLD PARAMETER:  , [LOAD, 'SET_TOUR_READY', 'SET_TOUR_PAGE']  ... replaced by reducer key filtering above instead

  enhancer = compose(
    applyMiddleware(thunk, cacheState),
    devTools({
      name: Platform.OS,
      hostname: '10.0.1.201',
      port: 5678,
      filters: {blacklist: ['REDUX_STORAGE_SAVE']}
    })
  );

  //reset reducer state on LOGOUT
  const appReducer = combineReducers(reducers);
  const rootReducer = (state, action) => {
    if (action.type === LOGOUT) {
      state = undefined;
    }

    return appReducer(state, action);
  }

  reducer = storage.reducer(rootReducer);


  store = createStore(reducer, enhancer);

  //retreive previously cached state and inject into Redux store!
  const load = storage.createLoader(engine);
  load(store)
      .then((newState) => console.log('Loaded state:', newState))
      .catch(() => console.log('Failed to load previous state'));


  if(module.hot) {
    module.hot.accept(() => {
      let nextRootReducer = storage.reducer(rootReducer);
      store.replaceReducer(nextRootReducer);

      load(store)
          .then((newState) => console.log('Loaded state:', newState))
    });
  }

  return store;
}

它应该为您提供一个可靠的示例,说明如何将各种中间件与module.hot.accept 一起使用。 ...就“循环引用”而言——唯一要做的就是检查你的减速器并确保它们不会相互导入。我想我实际上已经看到了这个确切的问题——ES6 模块可以正确地解决循环初始构建,但也许 HMR 构建过程不能。就这样。所以你最终认为你的代码可以工作,但它基本上不支持 HMR。我会设置一个快速测试应用程序并实现他们的hot.module.accept 代码并验证它是否适合您。也许你必须调整一件事——但由于你的代码太少,很容易找到——然后在你自己的代码中进行同样的修复。如果这还没有解决问题,那么暂时最小化您在应用程序中使用 redux 所做的事情,直到您找出导致问题的原因。 ..希望我对你有更多的建议。

【讨论】:

    猜你喜欢
    • 2016-11-14
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    相关资源
    最近更新 更多