How to reset all states of ngrx/store?

Hongbo Miao picture Hongbo Miao · Sep 5, 2016 · Viewed 19.2k times · Source

I am using Angular 2 with ngrx/store. I want to reset the whole store states when user dispatch USER_LOGOUT.

I read the Dan Abramov's answer of How to reset the state of a Redux store?, but I didn't figure out how to write rootReducer correctly and where to put it when using ngrx/store.

Or is there any other way to handle this in ngrx/store?

bootstrap(App, [
    provideStore(
      compose(
        storeFreeze,
        storeLogger(),
        combineReducers
      )({
        router: routerReducer,
        foo: fooReducer,
        bar: barReducer
      })
    )
  ]);

Answer

David Bulté picture David Bulté · Jul 26, 2017

In ngrx/store 4.x, this can be accomplished with metareducers. As I understand it, all actions are passing through the metareducers before being handed over to the feature reducers. This gives us the opportunity to change/reset the state first.

Here's an example.

This is my metareducer function: in case the action is of type LOGOUT, the state is re-initialized.

function logout(reducer) {
  return function (state, action) {
    return reducer(action.type === LOGOUT ? undefined : state, action);
  }
}

Below you see how the metareducer is configured along with the feature reducers. Should there be more than 1 metareducer, then they are evaluated from right to left

StoreModule.forRoot({rooms: roomReducer, user: userReducer}, {metaReducers: [logout]})

Finally, I also have an @effect where I navigate to the login page

@Effect({dispatch: false}) logout: Observable<Action> = 
this.actions$.ofType(LOGOUT)
  .do(() => {
    // ... some more stuff here ...
    this.router.navigate(['/login page'])
});