Angular,ngrx存储localstorage:存储在localstorage中的映射无法重新水合



几天来,我一直在努力从本地存储加载Map。在action reducer中创建了一个Map,并成功地将其序列化并保存到本地存储中。在刷新时加载(标志rehydrate被设置为true)会出现问题。Map似乎已成功反序列化,但在@ngrx/store/init操作后(仅在刷新后),它并不以新状态存在,而是只有{}(空对象)。我还想知道为什么在第一次初始化(页面加载;本地存储为空)之后是null(这是正确的),而在其他初始化(刷新)之后则是{}

我也试过replacerreviver的功能

  • replacer:JSON.stringify文档中指定的replacer函数
  • reviver:在JSON.parse文档中指定的reviver函数

但没有成功。

我创建了Stacklitz项目。

感谢您的帮助。

问题的原因是默认用于恢复数据的deepmerge包不支持Map and Set

为了修复它,你需要

  1. 用深度合并ts替换深度合并
  2. mergeReducer添加到ngrx-store-localstorage配置

这是更新的演示

import { deepmerge } from "deepmerge-ts";
const INIT_ACTION = '@ngrx/store/init';
const UPDATE_ACTION = '@ngrx/store/update-reducers';
export function localStorageSyncReducer(
reducer: ActionReducer<any>
): ActionReducer<any> {
return localStorageSync({
keys: [
{
map: {
serialize: (map) => Array.from(map.entries()),
deserialize: (map) => new Map(map),
},
},
],
rehydrate: true,
mergeReducer(state, rehydratedState, action) {
if ((action.type === INIT_ACTION || action.type === UPDATE_ACTION) && rehydratedState) {
state = deepmerge(state, rehydratedState);
}

return state;
},
removeOnUndefined: true,
restoreDates: true,
})(reducer);
}

我自己试过了,我看到了同样的东西
奇怪的是,github上没有关于这方面的问题。所以我不确定这是一个变通办法还是一个解决方案。

在文档中,您可以看到:

mergeReducer(可选)(状态:任意,再水合状态:任意、操作:任意)=>any:定义用于将存储中的重新水合状态与ngrx存储中的状态合并的还原器。如果未指定,则默认对INIT_ACTION或UPDATE_ACTION执行完全深度合并。

因此rehydratedState被解析为一个分离的状态,然后与原始状态合并。也许这就是为什么我们总是看到{}——合并状态的原因。

为了克服这一点,我宣布mergeReducer直接返回再水合状态

return localStorageSync({
keys: [
...
],
...
mergeReducer: (state: any, rehydratedState: any, action: any) => {
return rehydratedState;
}
})(reducer);

我想,对于更多的自定义状态值,您还需要在这个函数中自己合并它。

最新更新