在Angular应用中使用NGRX来管理状态时,我们可以通过一些技巧来防止发出重复的请求,尤其是在使用相同参数的情况下。下面是一个解决方法的代码示例:
import { createAction, props } from '@ngrx/store';
export const fetchUser = createAction('[User] Fetch User', props<{ id: string }>());
export const fetchUserSuccess = createAction('[User] Fetch User Success', props<{ user: User }>());
export const fetchUserFailure = createAction('[User] Fetch User Failure', props<{ error: string }>());
import { createReducer, on } from '@ngrx/store';
import { fetchUser, fetchUserSuccess, fetchUserFailure } from './user.actions';
export interface UserState {
user: User | null;
loading: boolean;
error: string | null;
}
export const initialState: UserState = {
user: null,
loading: false,
error: null
};
export const userReducer = createReducer(
initialState,
on(fetchUser, state => ({
...state,
loading: true,
error: null
})),
on(fetchUserSuccess, (state, { user }) => ({
...state,
user,
loading: false,
error: null
})),
on(fetchUserFailure, (state, { error }) => ({
...state,
loading: false,
error
}))
);
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { fetchUser } from './user.actions';
import { selectUserLoading, selectUserError, selectUser } from './user.selectors';
@Component({
selector: 'app-user',
template: `
Loading...
{{ error }}
User: {{ user.name }}
`
})
export class UserComponent {
loading$ = this.store.select(selectUserLoading);
error$ = this.store.select(selectUserError);
user$ = this.store.select(selectUser);
constructor(private store: Store) {}
ngOnInit() {
this.store.dispatch(fetchUser({ id: '123' }));
}
}
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { mergeMap, filter } from 'rxjs/operators';
import { fetchUser, fetchUserSuccess, fetchUserFailure } from './user.actions';
import { UserService } from './user.service';
@Injectable()
export class UserEffects {
fetchUser$ = createEffect(() =>
this.actions$.pipe(
ofType(fetchUser),
mergeMap(action =>
this.userService.getUser(action.id).pipe(
filter(user => !user), // 过滤掉已经获取到的用户
map(user => fetchUserSuccess({ user })),
catchError(error => of(fetchUserFailure({ error })))
)
)
)
);
constructor(
private actions$: Actions,
private userService: UserService
) {}
}
在上述代码中,我们使用了一个filter操作符来过滤掉已经获取到的用户,这样就可以防止重复的请求被发送到服务器。如果用户已经存在于状态中,我们可以选择不发出请求,或者在发出请求之前先检查用户状态。这取决于你的应用程序的需求。
通过以上的解决方法,我们可以确保在使用相同参数的情况下,不会发出重复的请求,并且有效地管理应用程序的状态。