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

时间:2019-05-26 09:03:06

标签: javascript reactjs redux react-redux reselect

我有以下选择器:

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

然后一切正常,选择器不会在每次调用时重新计算。似乎我在选择器概念中缺少了一些东西。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

更新

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

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

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


原始答案:

简而言之,reselect根据身份检查===确定输入选择器的更改。

因此,如果输入选择器始终创建并返回一个新的对象或数组,则每次都会重新计算选择器。

为了解决重新计算问题:

  1. 确保输入选择器始终返回引用,而不是新对象/数组。
  2. 或者,如果新对象/数组是正确的返回值,则必须customize the equalityCheck for defaultMemoize

来自reselect文档:

Why is my selector recomputing when the input state stays the same?(请点击链接,有很多例子)

  

检查您的备忘录功能是否与状态更新功能(即,如果使用Redux的减速器)兼容。例如,使用createSelector创建的选择器意外重新计算,可能会在每次更新时接收一个新对象,而无论其包含的值是否已更改。 createSelector使用身份检查(===)来检测输入是否已更改,因此在每次更新时返回新对象意味着选择器将在每次更新时重新计算。