我正在尝试理解ngrx /效果。我已经构建了一个简单的函数,每次单击都会将数字增加1。但点击时它会进入无限循环,不确定是什么时候发生的。我确定我犯了一些愚蠢的错误。
monitor.effects.ts
@Injectable()
export class MonitorEffects {
@Effect()
compute$: Observable<Action> = this.actions$
.ofType(monitor.ActionTypes.INCREMENT)
.map((action: monitor.IncrementAction) => action.payload)
.switchMap(payload => {
return this.http.get('https://jsonplaceholder.typicode.com/users')
.map(data => new monitor.IncrementAction(payload+1))
.catch(err => of(new monitor.InitialAction(0)))
});
constructor(private actions$: Actions, private http:Http ) {};
}
monitor.component.ts
ngOnInit() {
this.storeSubsciber = this
.store
.select('monitor')
.subscribe((data: IMonitor.State) => {
this.value = data.value;
this.errorMsg = data.error;
this.currentState = data.currentState;
});
}
increment(value: number) {
this.store.dispatch(new monitorActions.IncrementAction(value));
}
monitor.reducer.ts
export const monitorReducer: ActionReducer<IMonitor.State> = (state = initialState, action: Actions) => {
switch (action.type) {
case ActionTypes.INCREMENT:
return Object.assign({}, { value: action.payload, currentState: ActionTypes.INCREMENT, error: null });
...
...
...
default:
return Object.assign({}, { value: 0, currentState: ActionTypes.INITIAL, error: null });
}
}
答案 0 :(得分:7)
Effect
允许您观看给定的操作类型,并在每次调度时对该操作做出反应。
因此,如果您在某些效果中观察动作X并从该效果中调出另一个动作X,您将最终处于无限循环中。
在您的情况下:您的操作属于.ofType(monitor.ActionTypes.INCREMENT)
类型,然后根据您的效果发送操作monitor.ActionTypes.INCREMENT
(从此部分我假设:monitor.IncrementAction(payload+1)
),然后触发效果再次,一次又一次,......
答案 1 :(得分:1)
我遇到了同样的问题,答案是我的效果并没有返回与当前效果所要执行的动作完全不同的动作。
就我的情感而言,我只做了.do()
,并且没有将其映射到新动作。那是我的问题。因为我不需要执行新操作,所以我做了一个NoopAction来获取回报。这意味着没有人应该在减速器中使用NoopAction。