调度动作后如何防止 NgRx 影响?
How to prevent NgRx effects after dispatching an action?
我的 Angular 应用程序遇到了一个非常奇怪的错误。我有一个注销按钮,当按下该按钮时,它会分派一些操作来设置商店中不再需要未定义的参数。我还有一个名为 Storage 的组件,它(除其他外)在其 NgOnInit()
方法中获取状态片段。该方法的结构如下:
this.store.pipe(select(userProfile)).pipe(
switchMap( user => {
if (!currentUser) {
throw new Error('User must be logged in');
}
// ... do something ...
return this.store.pipe(select(userResources));
}
),
switchMap(
response => {
// ... more operations ...
return ...
}
)
).subscribe(
response => {
console.log("GOT RESPONSE");
},
(error: HttpErrorResponse) => {
console.log(error);
console.log("GOT ERROR");
}
);
每次我显示这个组件并调用这个方法时,一切都很完美,我检索我需要的状态片段并将信息显示给用户。奇怪的是,每当我经过这个组件时(例如,我转到存储页面然后返回主页),如果我之后按下注销按钮,就会抛出错误 "User must be logged in" 作为 store.pipe 会再次执行,即使我不在显示该组件的页面中! ngOnInit()
本身不会重新执行或重新调用(毕竟当我按注销时我不在那个组件中,我只是路过)但是那部分代码被执行了,我不知道为什么。
此外,我提到的那部分代码似乎是按照我通过存储页面的次数执行的(例如,如果我通过存储页面三次,我会收到 "GOT ERROR" 消息三次之后)。
注销按钮会执行类似的操作:
this.authenticationService.logout();
this.router.navigateByUrl(`/`);
this.resourceStore.dispatch(new Logout());
this.store.dispatch(new Logout());
有什么想法吗?这里有某种我不知道的连锁反应吗?
订阅已超出组件的生命周期。一个常见的内存泄漏是在通过 ngOnDestroy 生命周期挂钩销毁组件时忘记取消订阅。
选择器也会在相关状态发生变化时触发,因此会重复执行
可以找到更全面的讨论here
您可以通过添加以下内容来修复您的代码:
takeUntil 方法
private destroyed$ = new Subject<void>()
ngOnDestroy() {
this.destroyed$.next()
this.destroyed$.complete()
}
this.store.pipe(select(userProfile)).pipe(
takeUntil(this.destroyed$),
... rest of RxJS stream and subscription
);
我的 Angular 应用程序遇到了一个非常奇怪的错误。我有一个注销按钮,当按下该按钮时,它会分派一些操作来设置商店中不再需要未定义的参数。我还有一个名为 Storage 的组件,它(除其他外)在其 NgOnInit()
方法中获取状态片段。该方法的结构如下:
this.store.pipe(select(userProfile)).pipe(
switchMap( user => {
if (!currentUser) {
throw new Error('User must be logged in');
}
// ... do something ...
return this.store.pipe(select(userResources));
}
),
switchMap(
response => {
// ... more operations ...
return ...
}
)
).subscribe(
response => {
console.log("GOT RESPONSE");
},
(error: HttpErrorResponse) => {
console.log(error);
console.log("GOT ERROR");
}
);
每次我显示这个组件并调用这个方法时,一切都很完美,我检索我需要的状态片段并将信息显示给用户。奇怪的是,每当我经过这个组件时(例如,我转到存储页面然后返回主页),如果我之后按下注销按钮,就会抛出错误 "User must be logged in" 作为 store.pipe 会再次执行,即使我不在显示该组件的页面中! ngOnInit()
本身不会重新执行或重新调用(毕竟当我按注销时我不在那个组件中,我只是路过)但是那部分代码被执行了,我不知道为什么。
此外,我提到的那部分代码似乎是按照我通过存储页面的次数执行的(例如,如果我通过存储页面三次,我会收到 "GOT ERROR" 消息三次之后)。
注销按钮会执行类似的操作:
this.authenticationService.logout();
this.router.navigateByUrl(`/`);
this.resourceStore.dispatch(new Logout());
this.store.dispatch(new Logout());
有什么想法吗?这里有某种我不知道的连锁反应吗?
订阅已超出组件的生命周期。一个常见的内存泄漏是在通过 ngOnDestroy 生命周期挂钩销毁组件时忘记取消订阅。
选择器也会在相关状态发生变化时触发,因此会重复执行
可以找到更全面的讨论here
您可以通过添加以下内容来修复您的代码:
takeUntil 方法
private destroyed$ = new Subject<void>()
ngOnDestroy() {
this.destroyed$.next()
this.destroyed$.complete()
}
this.store.pipe(select(userProfile)).pipe(
takeUntil(this.destroyed$),
... rest of RxJS stream and subscription
);