Reactjs 使用ejectSaga取消saga任务时,yield cancelled()不是';t触发
我正在使用Reactjs 使用ejectSaga取消saga任务时,yield cancelled()不是';t触发,reactjs,redux,react-redux,redux-saga,Reactjs,Redux,React Redux,Redux Saga,我正在使用react样板文件injectSaga/ejectSaga功能(),试图取消我的saga遇到了一个问题 tl;dr-当带有注入saga的组件卸载时,saga取消通过task.cancel()发生,但这不会在实际saga本身中触发(即,yield cancelled()未触发) 我像这样将我的传奇注入容器(使用react router v4和redux): injectSaga函数执行以下神奇功能: export default ({ key, saga, mode }) => W
react样板文件
injectSaga/ejectSaga功能(),试图取消我的saga遇到了一个问题
tl;dr-当带有注入saga的组件卸载时,saga取消通过task.cancel()发生,但这不会在实际saga本身中触发(即,yield cancelled()
未触发)
我像这样将我的传奇注入容器(使用react router v4和redux):
injectSaga
函数执行以下神奇功能:
export default ({ key, saga, mode }) => WrappedComponent => {
class InjectSaga extends React.Component {
static WrappedComponent = WrappedComponent;
static contextTypes = {
store: PropTypes.object.isRequired,
};
static displayName = `withSaga(${WrappedComponent.displayName ||
WrappedComponent.name ||
'Component'})`;
componentWillMount() {
const { injectSaga } = this.injectors;
injectSaga(key, { saga, mode }, this.props);
}
componentWillUnmount() {
const { ejectSaga } = this.injectors;
ejectSaga(key);
}
injectors = getInjectors(this.context.store);
render() {
return <WrappedComponent {...this.props} />;
}
}
return hoistNonReactStatics(InjectSaga, WrappedComponent);
};
saga注入工作正常-每次组件安装时,我都能清楚地看到在redux中调用和捕获的操作。在react样板文件
中的特定sagaInjectors.js
文件中,我找到了取消注入的sagas的特定行:
if (Reflect.has(store.injectedSagas, key)) {
const descriptor = store.injectedSagas[key];
if (descriptor.mode && descriptor.mode !== DAEMON) {
// the task is cancelled here
descriptor.task.cancel();
// we verify that the task is cancelled here - descriptor.task.isCancelled() returns true if we log it
// Clean up in production; in development we need `descriptor.saga` for hot reloading
if (process.env.NODE_ENV === 'production') {
// Need some value to be able to detect `ONCE_TILL_UNMOUNT` sagas in `injectSaga`
store.injectedSagas[key] = 'done'; // eslint-disable-line no-param-reassign
}
}
}
My
yield cancelled()
块从未运行,尽管任务已成功取消。关于取消传奇的工作原理,我有什么遗漏吗?有没有一种简单的方法可以让我轻松地处理我的传奇清理逻辑,以便在传奇即将被取消时使用?我想你误解了任务取消在redux传奇中的作用
watchSizesDraftsAga()
相对应的任务自行完成task.cancel()
什么也不做yield cancelled()
与watchSizesDraftsAga()
相对应的任务自行完成
然后task.cancel()
什么也不做
yield cancelled()。谢谢你的帮助!嗯,我觉得自己像个白痴——这就是当你花太多时间看东西时会发生的事情。谢谢你的帮助!
export function* watchSizesDraftsSaga() {
try {
let stuffWeLookingFor = yield select(selectStuff());
// waiting for stuff here
yield put( moveStuffOver(stuffWeLookingFor) );
// everything works fine here, page works as expected and stuff has been found
} finally {
if (yield cancelled()) {
// PROBLEM: when the saga is ejected via ejectSaga, this condition never happens
yield put( cleanStuffUp() );
}
}
}
if (Reflect.has(store.injectedSagas, key)) {
const descriptor = store.injectedSagas[key];
if (descriptor.mode && descriptor.mode !== DAEMON) {
// the task is cancelled here
descriptor.task.cancel();
// we verify that the task is cancelled here - descriptor.task.isCancelled() returns true if we log it
// Clean up in production; in development we need `descriptor.saga` for hot reloading
if (process.env.NODE_ENV === 'production') {
// Need some value to be able to detect `ONCE_TILL_UNMOUNT` sagas in `injectSaga`
store.injectedSagas[key] = 'done'; // eslint-disable-line no-param-reassign
}
}
}