состояние ngrx не определено, если не названо

#angular #ngrx #ngrx-store

#angular #ngrx #ngrx-хранилище

Вопрос:

Я осваиваюсь с ngrx, и у меня это работает … но у меня было чертовски много времени, и это неправильно по сравнению с каждым учебным пособием / пошаговым руководством, которые я видел в Интернете, и я хотел бы посмотреть, смогу ли я привести его в правильное состояние.

Мои проблемы в 2 раза:

  1. Если я не даю государству имя, оно не определено в браузере. Это работает:
 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) , как показывает большинство примеров, это приводит к неопределенному состоянию во время выполнения.

  1. Я считаю, что, потому что, если это так, я не могу ссылаться на состояние в корне и должен его извлечь. Например, это работает:
 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 кажется слишком нестабильным. Это карточный домик, и если что-то не на своем месте, все рушится, и очень мало способов определить, что происходит. Я откажусь от него как от решения для управления состоянием.