代码之家  ›  专栏  ›  技术社区  ›  Steven Evers

如果未命名,则ngrx状态未定义

  •  0
  • Steven Evers  · 技术社区  · 4 年前

    我正在掌握ngrx的窍门,我已经成功了……但我花了很多时间做了它,与我在网上看到的每一个教程/演练相比,它都是错误的,我想看看我是否能让它达到正确的状态。

    我的问题有两个:

    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
    

    所以我有点不知所措。我已经让它工作了,我可以在运行时存储状态并获取它,但它不是惯用的,而且似乎很脆弱。

    0 回复  |  直到 4 年前
        1
  •  1
  •   Yair Cohen    4 年前

    问题是,您将一个reducer导出为reducer,然后尝试使用它。您需要导出该reducer并创建一个reducers数组,用作您的reducer 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 { }