【问题标题】:how to reset whole store of ngrx 9?如何重置ngrx 9的整个商店?
【发布时间】:2020-11-16 17:08:27
【问题描述】:

我已经看到了同样的问题here,但由于我使用的是 ngrx9,我认为应该有稍微不同的解决方案。我在 app 模块中的代码和 reducer 是这样的

.....
StoreModule.forRoot(
  reducers,
  {
    metaReducers,
    runtimeChecks: {
      strictStateImmutability: true,
      strictActionImmutability: true
    }
  }),
 ...

我进口的减速机是

export const reducers: ActionReducerMap<AppState> = {
  [friendsReducer.friendsFeatureKey]: friendsReducer.reducer,
  [authReducer.authFeatureKey]: authReducer.reducer,
  ...
};

export const metaReducers: MetaReducer<AppState>[] = !environment.production ? [] : [];

我的LOGOUT 操作存储在auth.actions 中。 那么我应该如何包含 root reducer 来重置所有状态呢?

【问题讨论】:

    标签: angular typescript redux ngrx-store


    【解决方案1】:

    只需添加 metareducer 即可清除您的状态

    export function clearOnLogoutMetaReducer(reducer) {
       return function(state, action) {
          if(action.type === logout.type) {
            return reducer(undefined, action);
          }
          return reducer(state, action);
       }
    } 
    

    并将其添加到您的 metareducers 数组中

    【讨论】:

    • 谢谢,它有帮助。现在我有来自选择器的其他错误,但我会弄清楚的。好像我只需要退订其中的一些。
    • 我没有考虑到这一点。我会解决你的新问题的答案
    • 谢谢你,伙计。 "larchik prosto otkrivalsa" ;)
    • 如果您的选择器失败,很可能是由于@charles-desbiens 在他们的回答中提到的原因造成的。您确实想将状态重置回初始状态,并且在大多数情况下不是undefined
    【解决方案2】:

    接受的答案是我在 StackOverflow 上经常看到的建议,不幸的是,这是你永远不应该做的事情。

    问题

    如果你让你的状态可能未定义,你会遇到几个问题:

    1. 您连接到商店的任何内容(通常只是选择器)都必须以考虑潜在未定义值的方式编写。这会很快变得丑陋,如果犯了错误,可能会导致难以发现的错误。

    2. 如果 JavaScript 引擎操作的对象具有相同的“形状”,则它们的性能会更好。这个主题很复杂,但基本思想是,如果对象具有相同的形状,编译器可以使用内联缓存优化操作(这里有关于该主题的更详细的文章:https://mrale.ph/blog/2015/01/11/whats-up-with-monomorphism.html)。如果您只是通过使其未定义来重置您的状态,那么状态对象会改变形状,并且您会失去一些性能。在大多数应用程序中,这可能不会产生明显的影响,但需要注意。

    3. 您打破了 redux 设计模式的基本原则之一,即您应该维护一个具有一致接口的集中式状态存储。 redux 设计模式的卖点之一是,如果你遵循它,你就会知道你的应用程序状态将始终具有一致的接口,并且你永远不必担心状态的某些部分不存在,并且可能导致的问题。这就是为什么 reducer 总是从初始状态对象创建的,并且状态的属性是在加载它们的提供者时急切地创建的,而不是动态地添加到状态中的原因。如果你通过将 state 设置为 undefined 来重置你的 state,你就会失去这个保证,以及 redux 的一大块价值。

    解决方案

    要清除存储,您需要调度一个简化为新初始状态对象的操作。 ngrx/redux 的一大优点是动作是沿着单个流调度的。这意味着一个功能商店(在您的情况下为“朋友”)中的减速器可以侦听另一个商店中的操作(在您的情况下为“身份验证”)。因此,在您的 friends.reducer.ts 中执行以下操作:

      import * as AuthActions from 'wherever/your/auth/actions/are';
      
      // Replace this with actual interface
      export interface FriendsState {
        friends: string[];
      }
    
      // Replace this with actual object
      export const initialFriendsState:FriendsState = {
        friends: [],
      }
    
      export const reducer = createReducer(
      initialFriendsState,
      on(AuthActions.LOGOUT, (state: FriendsState) => ({...initialFriendsState})),
      on(FriendsActions.GET_FRIENDS (state: FriendsState, {friends}) => ({...state, friends}) 
      //...whatever other reducers you have in your friends store
    );
       
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    • 2022-01-09
    • 2016-09-16
    • 2021-01-20
    • 2018-10-24
    • 1970-01-01
    • 2020-08-31
    相关资源
    最近更新 更多