#angular #ngrx #ngrx-store
#angular #ngrx #ngrx-хранилище
Вопрос:
Я осваиваюсь с ngrx, и у меня это работает … но у меня было чертовски много времени, и это неправильно по сравнению с каждым учебным пособием / пошаговым руководством, которые я видел в Интернете, и я хотел бы посмотреть, смогу ли я привести его в правильное состояние.
Мои проблемы в 2 раза:
- Если я не даю государству имя, оно не определено в браузере. Это работает:
import { reducers } from './state/app.reducers';
@NgModule({
declarations: [
AppComponent,
],
imports: [
StoreModule.forRoot({ appState: reducers }),
!environment.production ? StoreDevtoolsModule.instrument() : [],
EffectsModule.forRoot([AppEffects]),
StoreRouterConnectingModule.forRoot()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
но StoreModule.forRoot(reducers)
, как показывает большинство примеров, это приводит к неопределенному состоянию во время выполнения.
- Я считаю, что, потому что, если это так, я не могу ссылаться на состояние в корне и должен его извлечь. Например, это работает:
export class MyComponent implements OnInit {
state$: Observable<AppState>;
userId$: Observable<string>;
constructor(
private store: Store<{appState: AppState}>
) {
this.state$ = store.select('appState');
}
ngOnInit(): void {
this.userId$ = this.state$.pipe(select(s => s.userId));
}
}
Я не могу отключить состояние напрямую, как в большинстве примеров, и это вообще не будет работать при вводе, private store Store<AppState>
как показывает большинство примеров.
Если это поможет, мое состояние во время выполнения выглядит следующим образом:
{
appState: {
userId: 'd229b5ef-b7a8-2600-6eed-427ee7b10637',
userName: 'test',
}
}
Для справки…
// app/state/app.state.ts
export interface AppState {
userId: string;
userName: string;
}
export const initialState: AppState = {
userId: null,
userName: null
}
// app/state/app.reducers.ts
import { initialState } from './app.state';
const reducer = createReducer(
initialState,
on(updateUser, (state, { userId, userName })=> (
{
...state,
userId: userId,
userName: userName
}))
);
export function reducers(state, action) {
return reducer(state, action);
}
// app/state/app.selectors.ts
import { AppState } from './app.state';
export const selectUserId = (state: AppState) => state.userId
Так что я немного в недоумении. У меня это работает, где я могу сохранять состояние и получать его во время выполнения, но оно не идиоматично и кажется очень хрупким.
Комментарии:
1. пожалуйста, обратитесь к официальному документу ngrx.io/guide/store для пункта 5.
Ответ №1:
Проблема в том, что вы экспортируете один редуктор как редукторы, а затем пытаетесь его использовать. Вам нужно экспортировать этот один редуктор и создать массив редукторов, которые вы будете использовать в качестве редукторов в вашем StoreModule.forRoot()
. Пример кода:
// app/state/app.reducers.ts
import { initialState } from './app.state';
const reducer = createReducer(
initialState,
on(updateUser, (state, { userId, userName })=> (
{
...state,
userId: userId,
userName: userName
}))
);
export function reducer(state, action) { // changed from 'reducers' to reducer
return reducer(state, action);
}
Создайте новый файл под названием index.ts
:
// app/state/index.ts
import * as fromApp from 'app/state/app.reducer.ts',
export const reducers = [
appState: fromApp.reducer
]
Затем импортируйте редукторы:
import { reducers } from './state/index.ts';
@NgModule({
declarations: [
AppComponent,
],
imports: [
StoreModule.forRoot(reducers),
!environment.production ? StoreDevtoolsModule.instrument() : [],
EffectsModule.forRoot([AppEffects]),
StoreRouterConnectingModule.forRoot()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Комментарии:
1. Спасибо за ответ, но, похоже, это не очень помогает / помогает. Результатом является то, что он устанавливает именованное состояние на ‘0’ вместо AppState, и мои селекторы тоже больше не работают. Я ценю помощь, но ngrx кажется слишком нестабильным. Это карточный домик, и если что-то не на своем месте, все рушится, и очень мало способов определить, что происходит. Я откажусь от него как от решения для управления состоянием.