基于单个输入选择器而不是所有输入选择器记忆重新选择选择器输出 [英] Memoize Reselect selector output based on a single input selector instead of all
问题描述
我有一个 Reselect 选择器,它将一组选定的 id 映射到规范化存储中的对象.
I have a Reselect selector that maps an array of chosen ids into objects from a normalized store.
const activeObjectsSelector = createSelector(
state => state.activeIds,
state => state.objects.byId,
(activeIds, objectsById) => activeIds.map(id => objectsById[id])
)
问题在于,只要将新对象添加到规范化存储中,它就会破坏缓存并重新运行,因为 state.objects.byId
的值发生了变化.我关心破坏缓存的唯一变化是 state.activeIds
的值.这可能吗?
The problem is that it busts the cache and re-runs anytime new objects are added to the normalized store, because the value of state.objects.byId
changes. The only change I care about busting the cache is the value of state.activeIds
. Is this possible?
推荐答案
您可以为此使用 reselect 的 defaultMemoize 来记忆映射的结果,方法是将其传递给记忆化函数,该函数将数组的项作为参数:
You can use defaultMemoize of reselect for this to memoize the result of the map by passing it to a memoized function that will take the items of the array as arguments:
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>
这篇关于基于单个输入选择器而不是所有输入选择器记忆重新选择选择器输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!