NgRx 在 loginSuccess 操作上重定向到仪表板

NgRx redirect to dashboard on loginSuccess Action

我正在学习 NgRx,我有一个基本问题。我一直在查看示例项目和其他答案,它们都是 2017 年的,那里的架构有点不同。

我正在实现登录功能,到目前为止一切正常,正在调用操作,已发出休息 Api 请求等。我唯一的问题是:我在哪里将用户重定向到仪表板?

操作:

export const loginAction = createAction(
    '[Login Page] User Login',
    props<{ login: string; password: string }>()
);

export const loginSuccessAction = createAction(
    '[Auth] Login Complete',
    props<{user: UserModel}>()
);

export const loginFailAction = createAction('[Auth] Login Fail', props<{error: any}>());

减速器:

export interface AuthState{
    isLoggedIn: boolean;
    user: UserModel | null;
}
export const initialState: AuthState = {
    isLoggedIn: false,
    user: null
};

const _authReducer = createReducer(
    initialState,
    on(loginAction, (state) => ({...state, isLoggedIn: false, user: null})),
    on(loginSuccessAction, (state, {user}) => ({...state, isLoggedIn: true, user: user})),
    on(loginFailAction, (state) => ({ isLoggedIn: false, user: null }))
);

// tslint:disable-next-line:typedef
export function authReducer(state, action) {
    return _authReducer(state, action);
}

效果:

@Injectable()
export class AuthEffects {
    constructor(
        private actions$: Actions,
        private authService: AuthService
    ) {}

    @Effect()
    login$ = createEffect(() =>
        this.actions$.pipe(
            ofType(loginAction),
            exhaustMap(action =>
                this.authService.login(action.login, action.password).pipe(
                    map(user => loginSuccessAction({user: user.redmine_user})),
                    catchError(error => of(loginFailAction({ error })))
                )
            )
        )
    );
}

在我的组件中:

ngOnInit(): void
{
    this.loginForm = this._formBuilder.group({
        login   : ['', Validators.required],
        password: ['', Validators.required]
    });
}

onLogin(): void{
    this._store.dispatch(loginAction(this.loginForm.value));

}

ngOnDestroy(): void {

}

如我所说,操作已成功触发。我可以看到 loginSuccessAction 在 Redux 开发工具中被调用。我见过有人在效果中进行重定向,但这是正确的地方吗?如果没有,我应该在哪里做?有没有类似听动作的东西?

如果我没理解错的话,您是在询问用户登录后在何处执行重定向,但不是在技术意义上如何进行,而是在架构意义上是在正确的位置进行重定向。

让我们回顾一下您的选择:

  1. 在效果中重定向 - 这是您的第一个选项,在将成功操作分派给减速器之前或之后在效果中重定向。

  2. 从服务重定向 - 您也可以在服务之后重定向,例如:

myService(): void {
 return this.http.get(url).pipe(
  tap(() => this.router.navigate([navigationURL]))
 )
}

  1. 其他选项 - 其他选项也是可能的,在你的问题中你问是否有什么东西可以听动作,这几乎就是效果的目的,听操作,但您也可以使用 subscribe 收听 Observable 发射,并在发生这种情况时重定向,我不推荐这种方法。

我认为添加 subscriptions 会给项目增加不必要的复杂性,因为必须管理 subscriptions

那怎么办?

老实说,这取决于你,这两个选项似乎都有效,我不会说任何一个都是不好的做法。我个人更喜欢保持我的效果清洁并在服务中进行。我觉得该服务更适合处理副作用,并且在测试时也使它更干净一些,但这是我个人的看法。

要记住的重要一点是,这两个选项都是有效的,不要增加不必要的复杂性。

还有一个小案例可能适用于您,如果您需要用户在重定向前位于 store 中,最好在向减速器。如果您正在使用 Observables,它会以任何一种方式工作,但如果它们之间有紧密的关系,可能会更容易理解。