Redux Reselect - 带参数输入的选择器正在重新计算

Redux Reselect - selector with argument input is recalculating

我有以下选择器:

const getAllAddresses = (withStartEnd) => 
    createSelector(
        [getAllAddressesSelector, getStartAddressSelector, getEndAddressSelector],
        (all, startAddress, endAddress) => {
            if (!withStartEnd) return [...Object.values(all)];
            return [startAddress, ...Object.values(all), endAddress];
        }
    );

我注意到选择器每次都在重新计算,allstartAddressendAddress 时的事件不会改变。如果我删除选择器函数的输入,变成这样:

const getAllAddresses = (
    createSelector(
        [getAllAddressesSelector, getStartAddressSelector, getEndAddressSelector],
        (all, startAddress, endAddress) => {
            return [startAddress, ...Object.values(all), endAddress];
        }
    )
);

然后一切都按预期工作,选择器不会在每次调用时重新计算。好像我在选择器概念中遗漏了一些东西。任何帮助将不胜感激。

更新:

请参考How do I create a selector that takes an argument?

简而言之:只有当您传递静态参数并在 mapStateToProps 之外创建工厂函数时,您的操作方式才会起作用。对于动态参数,它更复杂,请遵循我上面提到的资源。

每次调用 mapStateToProps 时都会重新计算您的选择器的原因是调用 getAllAddresses 会创建一个新的 createSelector 实例,并且记忆将不起作用。


原回答:

简而言之,reselect 确定输入选择器的变化,基于身份检查===

因此,如果您的输入选择器总是创建并 return 一个新的对象或数组,那么您的选择器每次都会重新计算。

为了解决重新计算问题:

  1. 确保你的输入选择器总是return一个引用,而不是新的对象/数组。
  2. 或者,如果新对象/数组是正确的 returned 值,那么您必须 customize the equalityCheck for defaultMemoize

来自 reselect 文档:

Why is my selector recomputing when the input state stays the same?(请关注link,里面有很好的例子)

Check that your memoization function is compatible with your state update function (i.e. the reducer if you are using Redux). For example, a selector created with createSelector that recomputes unexpectedly may be receiving a new object on each update whether the values it contains have changed or not. createSelector uses an identity check (===) to detect that an input has changed, so returning a new object on each update means that the selector will recompute on each update.