NGRX 效果 - 为具有 {dispatch: false} 的效果分派动作是不好的做法吗?
NGRX effects - is it bad practice to dispatch actions for effects that have {dispatch: false}?
我有一个可能会或可能不会发送操作的效果:
handleMainAccount$ = createEffect(() => {
return this._actions$.pipe(
ofType(setUserDetails),
tap( (details) => {
if (details?.mainAccount) {
const fakeData = { foo: 'bar'};
this._accountHttpSvc.updateAccount(fakeData).pipe(
take(1), // so we don't have to unsub
map((res) => {
this._userStore.dispatch(setMainAccount({fakeData}));
}),
).subscribe();
}
// else
// we are not dispatching any action
})
);
} , { dispatch: false } ); // setting as false, because we may or may not dispatch an action
我将 dispatch 设为 false,因为有时此效果可能不会派发动作。
这是不好的做法吗?
如果有的话会有什么负面影响?
恕我直言,这是一种不好的做法。我将效果分为两类:
- 发出动作的效果
- 没有的效果
你的有点“两者兼而有之”。如果需求发生变化,测试和管理就会变得更加困难。
此外,您还在效果中手动订阅:这也是一种不好的做法!使用此代码,您没有扁平化运算符所拥有的控制级别(例如,取消之前的请求)。
作为一般指南,假设您遇到这种情况:
map(action => condition ? otherAction : null)
这显然行不通,因为 null
不是有效的操作。
因此,将 map
更改为 switchMap
(或其他扁平化运算符)并按如下方式修改您的代码:
import { switchMap, of, EMPTY } from 'rxjs';
...
switchMap(action => condition ? of(otherAction) : EMPTY)
在您的场景中,您希望有条件地执行请求。应该是这样的,而不是你的 tap
:
switchMap(condition => {
if (!condition) {
return EMPTY
}
return this.service.update(...).pipe(
take(1),
map(x => yourAction())
)
})
显然,您可以使用任何其他展平运算符来代替 switchMap
。使用 switchMap
并发请求将取消前一个请求,使用 mergeMap
它们将被并行处理,使用 concatMap
它们将被排队,使用 exhaustMap
第二个如果之前的调用尚未完成,则不会有任何效果。
我有一个可能会或可能不会发送操作的效果:
handleMainAccount$ = createEffect(() => {
return this._actions$.pipe(
ofType(setUserDetails),
tap( (details) => {
if (details?.mainAccount) {
const fakeData = { foo: 'bar'};
this._accountHttpSvc.updateAccount(fakeData).pipe(
take(1), // so we don't have to unsub
map((res) => {
this._userStore.dispatch(setMainAccount({fakeData}));
}),
).subscribe();
}
// else
// we are not dispatching any action
})
);
} , { dispatch: false } ); // setting as false, because we may or may not dispatch an action
我将 dispatch 设为 false,因为有时此效果可能不会派发动作。 这是不好的做法吗? 如果有的话会有什么负面影响?
恕我直言,这是一种不好的做法。我将效果分为两类:
- 发出动作的效果
- 没有的效果
你的有点“两者兼而有之”。如果需求发生变化,测试和管理就会变得更加困难。
此外,您还在效果中手动订阅:这也是一种不好的做法!使用此代码,您没有扁平化运算符所拥有的控制级别(例如,取消之前的请求)。
作为一般指南,假设您遇到这种情况:
map(action => condition ? otherAction : null)
这显然行不通,因为 null
不是有效的操作。
因此,将 map
更改为 switchMap
(或其他扁平化运算符)并按如下方式修改您的代码:
import { switchMap, of, EMPTY } from 'rxjs';
...
switchMap(action => condition ? of(otherAction) : EMPTY)
在您的场景中,您希望有条件地执行请求。应该是这样的,而不是你的 tap
:
switchMap(condition => {
if (!condition) {
return EMPTY
}
return this.service.update(...).pipe(
take(1),
map(x => yourAction())
)
})
显然,您可以使用任何其他展平运算符来代替 switchMap
。使用 switchMap
并发请求将取消前一个请求,使用 mergeMap
它们将被并行处理,使用 concatMap
它们将被排队,使用 exhaustMap
第二个如果之前的调用尚未完成,则不会有任何效果。