本文介绍了Redux Saga 过早地被 LOCATION_CHANGE 停止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I'm injecting Sagas dynamically when the route loads

  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,在商店创建期间创建.

where store.runSaga is sagaMiddleware.run, created during store creation.

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

When the route loads the saga is successfully started. It's listening for actions.

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,它会成功地完成它必须做的任何事情.当我离开页面时,反应路由器调用 LOCATION_CHANGE,Saga 控制台停止 mySagaFunction"暗示它成功退出了 while 循环.

When I load the route, "Start mySagaFunction" is consoled. If I dispatch SOME_HOME_PAGE_ACTION, it successfully does whatever it has to do.When I leave the page, react router calls LOCATION_CHANGE, and Saga consoles "Stop mySagaFunction" implying it successfully quit the while loop.

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

Then I go to another route and come back to this route.This time LOCATION_CHANGE is dispatched by router, as expected. But Saga is starting and then stopping immediately. My console goes like this:

Start mySagaFunction
Stop mySagaFunction

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

In Redux dev tools I see only one LOCATION_CHANGE. How do I figure out why the Saga is starting and immediately stopping? It happens only if I come back to the route.

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

I thought maybe LOCATION_CHANGE was being dispatched late. But no. In my reducers I consoled the action type. Reducer is called first with LOCATION_CHANGE and saga starts and then saga stops.

我使用 Link 在页面之间导航.我也试过 browserHistory.push(url)dispatch(push(url)) .结果一样.

I'm using Link to navigate between pages. I tried browserHistory.push(url) and dispatch(push(url)) as well. Same result.

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

Note: I got the code for injecting the sagas from react-boilerplate. I have only taken this code and I'm not using the boilerplate itself. I ran the boilerplate and this bug is not happening there. Differences are:

  • 它在 syncHistoryWithStore 中使用 selectLocationState.我的整个商店都不是一成不变的,所以我不需要那个.
  • 它使用自己的 routeReducer 而不是 react-router-redux 中的 routerReducer.我不知道为什么,也许是因为完整的不可变存储.
  • It's using selectLocationState in syncHistoryWithStore. My whole store is not Immutable so I don't need that.
  • It's using it's own routeReducer instead of routerReducer from react-router-redux. I don't know why, maybe because of full immutable store.

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

Anyways in the boiler plate code I removed the above two points and still the scenario is not occurring.

推荐答案

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

The route had an onEnter redirect and hence LOCATION_CHANGE would be dispatched twice thereby cancelling the saga.

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

解决方法:

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

I'm dispatching a LEAVE_PAGE action in onLeave hook for every page that injects sagas

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

在传奇中观察那个特定的动作:

and in the saga watch for that particular action:

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

这篇关于Redux Saga 过早地被 LOCATION_CHANGE 停止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 17:37