首页 > 解决方案 > 导入服务器状态后的角度通用,@ngrx/store/update-reducers 操作擦除存储

问题描述

在 ssr 模式下的 Angular Universal 项目中,成功将转移状态导入存储后,下一个调度@ngrx/store/update-reducers的动作会擦除存储。实际上有多个 @ngrx/store/update-reducers动作被触发(> 10)。

在@ngrx/store-devtools(chrome 扩展名)中检查错误地显示,store after@ngrx/store/update-reducers仍然充满数据,但事实并非如此,我看到 cmp 中先前加载的数据在片刻后消失(当上述动作触发时)。

它只发生在 ssr 模式下,尽管@ngrx/store/update-reducers在 classic 的 @ngrx/store-devtools 中仍然存在多个ng serve

部门:角度 5.2.7,@ngrx/{商店,效果,商店开发工具,路由器商店} 5.2.0,铬 66

标签: angularngrxangular-universalngrx-store

解决方案


通常@ngrx/store/update-reducers从延迟加载的功能模块中添加减速器。因此,我假设在您的情况下,多个功能模块是延迟加载的。

最有可能发生的是在添加延迟加载模块的减速器之前设置了转移状态。默认情况下,ngrx 将清除所有未分配减速器的状态部分(这是在combineReducers运行在每个调度的操作上的函数中完成的)。

可能的解决方案:

1.在根模块中为功能模块分配默认reducer

StoreModule.forRoot(initialReducerMap, { initialState: getInitialState })
export function defaultReducer(state) { return state; }

export const initialReducerMap = {
    // this will make sure `feature1` and `feature2` parts are not cleared on next action
    feature1: defaultReducer,
    feature2: defaultReducer
} as ActionReducerMap<ApplicationState>;


export function getInitialState() {
    return {
        feature1: feature1.initialState,
        feature2: feature2.initialState
    };
}

此博客文章中的更多信息

2. 手动设置延迟加载模块的转移状态部分

import { ActionReducer, UPDATE } from "@ngrx/store";

let transferedState: any;
export function stateSetter(reducer: ActionReducer<any>): ActionReducer<any> {
  return function(state: any, action: any) {
    if (action.type === 'SET_ROOT_STATE') {
      transferedState = action.payload;
      return action.payload;
    }

    // on "update-reducers" set their initial transfered state
    if (action.type === UPDATE && transferedState && action.features) {
        const features: string[] = (action as any).features;
        const newState = { ...state };
        for (const feature of features) {
            newState[feature] = newState[feature] || transferedState[feature];
        }
        return reducer(newState, action);
    }

    return reducer(state, action);
  };
}

其他

参考这个github问题


推荐阅读