所以我在路线加载时动态注入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.runSaga
是sagaMiddleware.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
}
当我加载路线时,"启动mySagaFunction"安慰。如果我发送SOME_HOME_PAGE_ACTION,它会成功完成它必须做的任何事情。 当我离开页面时,路由器调用LOCATION_CHANGE和Saga控制台"停止mySagaFunction"暗示它成功退出了while循环。
然后我去另一条路线然后回到这条路线。 这次LOCATION_CHANGE由路由器调度,如预期的那样。但是佐贺正在开始然后立即停止。我的控制台是这样的:
Start mySagaFunction
Stop mySagaFunction
在Redux开发工具中,我只看到一个LOCATION_CHANGE。我如何弄清楚为什么佐贺开始并立即停止?只有当我回到路线时才会发生这种情况。
我想也许LOCATION_CHANGE被派遣了很晚。但不是。在我的减速器中,我安慰了动作类型。首先使用LOCATION_CHANGE调用Reducer,然后saga启动,然后saga停止。
我使用Link
在页面之间导航。我也尝试了browserHistory.push(url)
和dispatch(push(url))
。结果相同。
注意:我从react-boilerplate获得了注入传单的代码。我只使用了这段代码,而且我没有使用样板本身。我运行了样板,这个错误不会发生在那里。差异是:
selectLocationState
。我的整个商店都不是永恒的,所以我不需要那样。routeReducer
而不是routerReducer
中的react-router-redux
。我不知道为什么,也许是因为完全不可变的商店。无论如何,在锅炉板代码中,我删除了上述两点,但情况仍未发生。
答案 0 :(得分:2)
该路线有一个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
});