angular 导入服务器状态后通用,@ngrx/store/update-reducers 操作擦除存储

angular universal after import server state, @ngrx/store/update-reducers action wipes store

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

在@ngrx/store-devtools(chrome 扩展名)中检查不正确地显示 @ngrx/store/update-reducers 之后的存储仍然充满了数据,但事实并非如此,我看到之前在 cmp 中加载的数据消失了片刻之后(当这个提到的动作触发时)。

它只发生在 ssr 模式下,尽管在经典 ng serve.

中 @ngrx/store-devtools 中仍然存在多个 @ngrx/store/update-reducers

部门: angular 5.2.7, @ngrx/{store,effects,store-devtools,router-store} 5.2.0, chrome66

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

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

可能的解决方案:

1.在根模块中为功能模块分配默认减速器

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
    };
}

更多信息见this blog post

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);
  };
}

其他

参考this github issue