javascript - Memoize Reselect 选择器输出基于单个输入选择器而不是全部
问题描述
我有一个重新选择选择器,它将一组选定的 id 映射到规范化存储中的对象。
const activeObjectsSelector = createSelector(
state => state.activeIds,
state => state.objects.byId,
(activeIds, objectsById) => activeIds.map(id => objectsById[id])
)
问题是它会破坏缓存并在新对象添加到规范化存储时重新运行,因为值发生了state.objects.byId
变化。我关心破坏缓存的唯一变化是state.activeIds
. 这可能吗?
解决方案
您可以为此使用 reselect 的 defaultMemoize 来记忆地图的结果,方法是将其传递给一个记忆函数,该函数将数组的项目作为参数:
const { createSelector, defaultMemoize } = Reselect;
const state = {
activeIds: [1, 2],
objects: {
1: { name: 'one' },
2: { name: 'two' },
3: { name: 'three' },
},
};
const selectActiveIds = (state) => state.activeIds;
const selectObjects = (state) => state.objects;
const createMemoizedArray = () => {
const memArray = defaultMemoize((...array) => array);
return (array) => memArray.apply(null, array);
};
const createSelectAcitiveObjects = () => {
const memoizedArray = createMemoizedArray();
return createSelector(
selectActiveIds,
selectObjects,
(ids, objects) =>
memoizedArray(ids.map((id) => objects[id]))
);
};
const selectAcitiveObjects = createSelectAcitiveObjects();
const one = selectAcitiveObjects(state);
console.log('one is:',one);
const two = selectAcitiveObjects(state);
console.log('one is two', two === one);
const newState = { ...state, activeIds: [1, 2, 3] };
const three = selectAcitiveObjects(newState);
console.log('three is two', three === two);
<script src="https://cdnjs.cloudflare.com/ajax/libs/reselect/4.0.0/reselect.min.js"></script>
<div id="root"></div>
推荐阅读
- asp.net-core - 我可以在同一个项目中同时使用 Blazor 客户端和服务器端吗?更重要的是,我可以在同一个页面中使用它吗?
- javascript - 如何使用 lodash 将两个数组(数组 1d 和数组 2d)合并为一个对象
- prometheus - Prometheus 导出器客户端在源停止后继续发送最后一个值
- php - 使用 WP Query 在 wordpress 中显示最新的 100 个帖子,每页分页 5 个帖子
- amazon-web-services - amazon-Cloudformation 指标警报防止在没有信息时保持警惕
- java - 为什么我的应用程序在手机重启后尝试打开文件时会崩溃?
- laravel - 如何在 Laravel/Eloquent 中获得完整的关系
- c# - 托管在 Windows 服务中的 ASP.NET Core - 未提供静态文件(即 /wwwroot 的内容)
- java - 来自 mssql 数据库的快速流式批处理数据
- ios - 如何更改 Podfile 中的现有存储库 URL,将所有 pod 更新到新存储库