如何重置ngrx/store的所有状态?

How to reset all states of ngrx/store?

我正在使用 Angular 2 和 ngrx/store。我想在用户发送 USER_LOGOUT.

时重置整个商店状态

我读了 Dan Abramov 对 的回答,但我没有弄清楚如何正确地写 rootReducer 以及在使用 ngrx/store 时把它放在哪里。

或者在 ngrx/store 中是否有其他方法可以处理此问题?

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

此答案特定于 ngrx 版本 2。问题 解释了如何使用 ngrx 版本 4 完成相同的操作。


compose 构建 ngrx root reducer.

传递给 compose 的参数是 return 减速器的函数 - 由减速器组成,它们本身作为参数传递。您可以这样设置您的商店重置:

import { compose } from "@ngrx/core/compose";

...

bootstrap(App, [
  provideStore(
    compose(
      storeFreeze,
      storeLogger(),
      (reducer: Function) => {
        return function(state, action) {
          if (action.type === 'USER_LOGOUT') {
            state = undefined;
          }
          return reducer(state, action);
        };
      },
      combineReducers
    )({
      router: routerReducer,
      foo: fooReducer,
      bar: barReducer
    })
  )
]);

请注意,这将重置商店的所有状态 - 包括 router。如果这不是您想要的,您可以调整示例。

随着 NgModule 的引入,引导程序发生了变化,但您仍然将组合减速器传递给 provideStore:

import { compose } from "@ngrx/core/compose";
import { StoreModule } from "@ngrx/store";

@NgModule({
    ...
    imports: [
        ...
        StoreModule.provideStore(compose(...))
    ],
    ...

这不是一个真正的答案,但评论不会让我正确地格式化它。补充一下 cartant 所说的,如果你像这样设置你的类型:

export const ActionTypes = {
  LOGOUT:  type('[Environment] Logout of portal'),
  ....
}

这是您应该使用的详细说明。此外,如果您将根减速器命名为 rootReducer 而不是 reducer 那么您也会更改它。以下是经过编辑的示例:

(我把这个函数留在了我的 root reducer 中)

const developmentReducer: ActionReducer<State> = compose(...DEV_REDUCERS,
(rootReducer: Function) => {
    return function(state, action) {
      if (action.type === '[Environment] Logout of portal') {
        state = undefined;
      }
      return rootReducer(state, action);
    };
  }, combineReducers)(reducers);

在ngrx/store4.x中,这可以用Meta-reducers来完成。据我了解,所有操作在移交给特征缩减器之前都经过元缩减器。这让我们有机会change/reset状态第一。

这是一个例子。

这是我的 metareducer 函数:如果操作是 LOGOUT 类型,状态将重新初始化。

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

下面您将看到元减速器是如何与功能减速器一起配置的。如果有超过 1 个元减速器,则从右到左评估它们

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

最后,我还有一个@effect,我可以在其中导航到登录页面

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

与@ngrx/store": "^4.0.3" 这略有不同,因为有一些小的变化,所以我的 'clear state' 看起来像这样

import { ActionReducerMap } from '@ngrx/store';
import { ActionReducer, MetaReducer } from '@ngrx/store';

export const rootReducer: ActionReducerMap<StoreStates> = {
  points: pointsReducer,
  ...
};

export function clearState(reducer: ActionReducer<StoreStates>): ActionReducer<StoreStates> {
  return function(state: StoreStates, action: Action): StoreStates {
    if (action.type === 'CLEAR_STATE') {
      state = undefined;
    }
    return reducer(state, action);
  };
}
export const metaReducers: MetaReducer<StoreStates>[] = [clearState];

import { StoreModule } from '@ngrx/store';
import { metaReducers, rootReducer } from '../root.reducer';

export const imports: any = [
   StoreModule.forRoot(rootReducer, { metaReducers }),
   ...
]