3
votes

I have some questions of how individual states for each reducer is sliced. In a lot of tutorials online (like this one) there is a root global state defined manually that combines all individual states called AppState.

Is it correct to say that when we pass the object literal that contains all the reducers to StoreModule:

StoreModule.provideStore({r1: ReducerFunc1, r2: ReducerFunc2, ...})

the object keys r1 and r2 can be used to query slices of state when using string selector:

store.select("r1")

However, if we want type safety, we define the AppState interface, and make sure that the object keys matches the object keys of the reducer object literal passed to NgRx, so that we can use store.select(appstate => appstate.r1) (and is this the only useful case of AppState interface)?

2

2 Answers

4
votes

To have type safety set it up this way:

export interface AppState {
     auth: AuthState;
     contacts: ContactsState;
     events: EventsState;
}

Each slice would have it's own interface.

Then you set up your reducers

export const reducers: ActionReducerMap<AppState> = {
    auth: fromAuth.reducer;
    contacts: fromContacts.reducer;
    events: fromEvents.reducer;
}

Then in your app module

imports: [
    StoreModule.forRoot(reducers),
],

Your auth reducer, for example, would be defined like this

export function reducer(state: AuthState = initialAuthState,
                        action: Action) {

etc. Each reducer is called by it's key, the auth reducer and auth state.

0
votes

I think you have to setup the AppState interface. For example when you dependency inject the Store you can't do this:

constructor(private store: Store)

The Store has to take in an interface like so:

constructor(private store: Store<AppState>)

Given that you have to specify AppState you might want to always use the fat arrow function to get the AppState slice since you get type safety.

store.select(appstate => appstate.r1)