Итак, я начал использовать NGXS, и у меня возникли некоторые трудности с проверкой моего магазина через Redux Devtools.
У NGXS есть пакет инструментов разработчика, который интегрируется с Расширение Redux Devtools.
Я установил последнюю версию пакета (^ 3.2.0) и импортировал ее в импорт AppModule:
imports: [
NgxsModule.forRoot([ProjectState, AuthState], {developmentMode: true}),
...
NgxsReduxDevtoolsPluginModule.forRoot(),
]
На моем AuthState я сделал:
export class AuthState implements NgxsOnInit {
constructor(private auth: AuthService) {}
ngxsOnInit({dispatch}: StateContext<AuthStateModel>) {
console.info('State initialized, now getting auth');
dispatch(CheckAuthSession);
}
@Action(CheckAuthSession)
checkSession({patchState}: StateContext<AuthStateModel>) {
return this.auth.user$.pipe(
tap((user) => patchState({initialized: true, user: user})),
);
}
Когда я открываю консоль в Google Chrome, я получаю строку
console.info('State initialized, now getting auth')
И свойства Auth загружены. Хотя в Redux Devtools я вижу только:
Как вы видете:
CheckAuthSession не отправляетсяauth.initialized остается false, даже когда я записываю его в консоль, это true.Странно то, что когда я отправляю новое действие, расширение упоминает его, и состояние меняется на то, что было перед действие. Я не уверен, что это правильное поведение.
Обновление 1
Когда я добавляю канал take(1) перед tap в методе checkSession, он как-то работает. Понятия не имею почему.
Не могли бы вы поделиться кодом AuthService?
@VivekDoshi AuthService.user$ возвращает DocumentReference. Причина, по которой я не видел текущего состояния, заключалась в том, что подписка не была завершена. Итак, чтобы продолжать получать данные в реальном времени от наблюдателя и получать текущее состояние, мне пришлось отправить и выполнить действие, а затем исправить состояние в новом действии вместо исправления действия внутри tap(..).





Причина, по которой я не видел свое действие в инструментах разработки, заключалась в том, что действие никогда не заканчивалось, поскольку я не подписывался на него. Другими словами, если у вас есть действие, которое возвращает наблюдаемое, оно не будет отображаться в Devtools, пока подписка не будет завершена.
В моем примере я не хотел завершать подписку своего обработчика действий, потому что мне нужно было прослушивать каждое изменение моего user$.
Поэтому, чтобы сделать мой код разумным, я оставил метод без подписки, но внес несколько изменений:
patchState({initialized: true, user: user}) из checkSession, потому что тогда я бы не знал, изменилось ли состояние, поскольку действие не будет отображаться, потому что оно никогда не заканчивается.tap((user) => dispatch(new UpdateAuth(user)) в канал user$ внутри метода checkSession.onUpdateAuth(user: User), который вызывается при запуске действия UpdateAuth.вот так:
@Action(UpdateAuth)
onUpdateAuth({patchState}: StateContext<AuthStateModel>, {user}: UpdateAuth) {
patchState({user});
}
Потребовалось время, чтобы понять это, но, в конце концов, в этом гораздо больше смысла.
Возможно, вам будет полезно включить определение @State для вашего класса контейнера состояния. Кроме того, обычно диспетчерская получает новый экземпляр класса действия.