我当时在做一个React&Redux项目。该项目过去使用webpack-dev-middleware和热中间件进行热重载。

在将Redux Saga添加到项目中并将saga中间件添加到redux存储中之后。似乎每当我更改saga代码时,热重装就会中断并显示错误消息:



我了解Saga使用发电机,并且它与时间有关。是否可以使用Sagas热重新加载页面?就像Redux reducer 如何在热重装过程中自行更换一样。

谢谢!

最佳答案

我正在使用redux和redux-saga进行项目(但没有反应)。我使用sagaMiddleware.run()实现了sagas的热重载,但是您必须按所提供的链接(https://github.com/reactjs/react-redux/releases/tag/v2.0.0)中所述处理模块重载并替换reducer和sagas。

import { createStore } from 'redux';
import rootReducer from '../reducers/index';
import getSagas from '../sagas';

export default function configureStore(initialState) {
  const sagaMiddleware = createSagaMiddleware()
  const store = createStore(rootReducer, initialState, applyMiddleware(sagaMiddleware));
  let sagaTask = sagaMiddleware.run(function* () {
     yield getSagas()
  })
  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    module.hot.accept('../reducers', () => {
      const nextRootReducer = require('../reducers/index');
      store.replaceReducer(nextRootReducer);
    });
    module.hot.accept('../sagas', () => {
      const getNewSagas = require('../sagas');
      sagaTask.cancel()
      sagaTask.done.then(() => {
        sagaTask = sagaMiddleware.run(function* replacedSaga (action) {
          yield getNewSagas()
        })
      })
    })
  }

  return store;
}

需要注意的重要事项是getSagas()函数。它返回一个新创建的sagas生成器对象的数组,您不能从一些已经在运行的sagas中获得一些预先创建的对象。如果让这个数组
仅在一个模块中,您可以直接使用常量数组,但是如果您构建它
从不同的模块组成Sagas,您必须确保重新创建Sagas
因此,更好的方法是所有模块都导出创建函数,而不是导出固定的传奇或传奇数组。
例如,它可能是这样的函数:
export default () => [
  takeEvery(SOME_ACTION, someActionSaga),
  takeEvery(OTHER_ACTION, otherActionSaga),
]

显然,如果您有复杂的Sagas,则从头开始重新启动所有的Sagas。
使用内部状态,您将失去当前状态。

一种非常相似的方法是使用动态传奇代替调用sagaMidleware.run(),这是一种非常相似的解决方案,但是您可以重新加载sagas的子集并以不同方式处理它们。有关更多信息,请参见https://gist.github.com/mpolci/f44635dc761955730f8479b271151cf2

关于webpack - Redux Saga热装,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37148592/

10-09 05:19