Redux Saga 过早地被 LOCATION_CHANGE 停止

IT技术 reactjs redux react-router react-router-redux redux-saga
2021-05-14 02:43:27

所以我在路由加载时动态注入 Sagas

  path: '/home',
  name: 'home',
  getComponent(nextState, cb) {
    require.ensure([],
      require => {
        let HomePageReducer = require('./containers/HomePage/reducer').default;
        let HomePageSagas = require('./containers/HomePage/sagas').default;
        let HomePage = require('./containers/HomePage').default;

        injectReducer('home', HomePageReducer);
        injectSagas(HomePageSagas);

        cb(null, HomePage);
      })
  },

injectAsyncSagas 是这样的:

export function injectAsyncSagas(store) {
  return (sagas) => sagas.map(store.runSaga);
}

其中store.runSagasagaMiddleware.run,在商店创建期间创建。

当路由加载成功时,saga 启动。它正在倾听行动。

export function* mySagaFunction() {
    console.log("Start mySagaFunction");
    while (true) {
    const watcher = yield race({
      loadRepos: take(SOME_HOME_PAGE_ACTION),
      stop: take(LOCATION_CHANGE), // stop watching if user leaves page
    });

    if (watcher.stop) {
      console.log("Stop mySagaFunction", watcher.stop);
      break;
    }
    //other statements here to handle SOME_HOME_PAGE_ACTION
}

当我加载路线时,“Start mySagaFunction”得到安慰。如果我调度 SOME_HOME_PAGE_ACTION,它会成功地完成它必须做的任何事情。当我离开页面时,react-router调用 LOCATION_CHANGE,Saga 控制台“停止 mySagaFunction”暗示它成功退出了 while 循环。

然后我去另一条路线,然后回到这条路线。这次 LOCATION_CHANGE 由路由器调度,正如预期的那样。但是 Saga 正在启动,然后立即停止。我的控制台是这样的:

Start mySagaFunction
Stop mySagaFunction

在 Redux 开发工具中,我只看到一个 LOCATION_CHANGE。我如何找出 Saga 启动并立即停止的原因?只有当我回到路线时才会发生这种情况。

我想 LOCATION_CHANGE 可能被派送晚了。但不是。在我的减速器中,我安慰了动作类型。首先使用 LOCATION_CHANGE 调用 Reducer,然后 saga 开始,然后 saga 停止。

Link用来在页面之间导航。我试着browserHistory.push(url)dispatch(push(url))为好。结果一样。

注意:我从react-boilerplate得到了注入传奇的代码我只使用了这段代码,我没有使用样板本身。我运行了样板,这个错误没有发生在那里。区别在于:

  • selectLocationState在 syncHistoryWithStore 中使用我的整个商店都不是一成不变的,所以我不需要那个。
  • 它使用它自己的routeReducer而不是routerReducerfrom react-router-redux我不知道为什么,也许是因为完全不可变的存储。

无论如何,在样板代码中,我删除了上述两点,但仍然没有发生这种情况。

1个回答

该路由有一个 onEnter 重定向,因此 LOCATION_CHANGE 将被分派两次从而取消传奇。

{
    path: 'home',
    getComponent(nextState, cb) {
        require.ensure([], require => {...})
    },
    indexRoute: {
            onEnter: (nextState, replace) => replace('/home/A')
    }
}

解决方法:

我正在为每个注入传奇的页面在 onLeave 钩子中调度一个 LEAVE_PAGE 操作

onLeave: ()=> {
          store.dispatch({type: LEAVE_HOME_PAGE});
        }

在传奇中注意那个特定的动作:

const watcher = yield race({
  loadRepos: take(SOME_HOME_PAGE_ACTION),
  stop: take(LEAVE_HOME_PAGE), // stop watching if user leaves page
});