简体   繁体   English

NgRx 效果无限循环

[英]NgRx Effects infinite loop

I know that this question has been asked a million times on SO .我知道这个问题已经在 SO 上问了一百万次 But I need help.但我需要帮助。 I do realise I must be missing something crucial here.我确实意识到我必须在这里遗漏一些重要的东西。 But I'm not seeing it.但我没有看到。

Below code triggers an infinite loop.下面的代码触发了一个无限循环。 REMOVE_PROJECT is being dispatched only once. REMOVE_PROJECT 仅被分派一次。 REMOVE_PROJECT_SUCCESS is being triggered infinitely. REMOVE_PROJECT_SUCCESS 被无限触发。 'removed' is being logged infinitely. 'removed' 被无限记录。 I have no idea why.我不知道为什么。

All Actions have unique types.所有动作都有独特的类型。 dispatch: false is enabled for REMOVE_PROJECT_SUCCESS. dispatch: false为 REMOVE_PROJECT_SUCCESS 启用。

Actions:行动:

export const REMOVE_PROJECT = createAction(
    '[Project] Remove Project',
    props<{ id: string }>()
);

export const REMOVE_PROJECT_SUCCESS = createAction(
    '[Project] Remove Project Success',
);

Effects:效果:

@Effect()
removeProject$ = createEffect(() => this.actions$.pipe(
    ofType(ProjectActions.REMOVE_PROJECT),
    switchMap(props =>
        this.projects.removeProject(props.id).pipe(
           map(() => ({ type: '[Project] Remove Project Success'}),
        // have also tried
        // map(() => ProjectActions.REMOVE_PROJECT_SUCCESS())
        )
    ))
))


@Effect({ dispatch: false })
removeProjectSuccess$ = createEffect(() => this.actions$.pipe(
    ofType(ProjectActions.REMOVE_PROJECT_SUCCESS),
    tap(() => console.log('removed')),
))

Delete function:删除功能:

removeProject(projectId): Observable<void> {
    return from(this.db.doc('projects/' + projectId).ref.delete());
}

This is because you're using the @Effect() decorator with createEffect() .这是因为您将@Effect()装饰器与createEffect() They both do the same thing under the hood, likely triggering the infinite loop.他们都在幕后做同样的事情,可能会触发无限循环。 Remove EITHER the @Effect() annotations (recommended) or createEffect() (I'd leave this one).删除@Effect()注释(推荐)或createEffect() (我会留下这个)。

To be more specific, the createEffect() also takes {dispatch: false} as the second argument (after your observable pipe).更具体地说, createEffect()还将{dispatch: false}作为第二个参数(在您的可观察管道之后)。 Since you don't include this option for the second one, it just re-dispatches the actions you filtered with ofType , thereby firing the same actions over and over in the infinite loop you're experiencing.由于您没有在第二个选项中包含此选项,它只是重新分发您使用ofType过滤的操作,从而在您遇到的无限循环中ofType触发相同的操作。

Here's what the second effect should look like if you want to not dispatch:如果您不想分派,则第二个效果应该如下所示:

removeProjectSuccess$ = createEffect(() => this.actions$.pipe(
    ofType(ProjectActions.REMOVE_PROJECT_SUCCESS),
    tap(() => console.log('removed')),
), { dispatch: false })

Under the hood, both the decorator and the function add annotations to the injectable class that the EffectsModule consumes.引擎盖下,无论是装饰和功能添加注释注射类的EffectsModule消耗。 In this scenario, it makes an effect that will not dispatch, and a second one that dispatches by default.在这种情况下,它会产生一个不会调度的效果,而第二个效果会默认调度。 I hope this makes sense.我希望这是有道理的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM