【问题标题】:Redux Reselect - selector with argument input is recalculatingRedux Reselect - 带有参数输入的选择器正在重新计算
【发布时间】:2019-05-26 09:03:05
【问题描述】:

我有以下选择器:

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

我注意到选择器每次都在重新计算,all、startAddress 和 endAddress 时的事件没有改变。如果我删除选择器函数的输入,如下所示:

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

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

【问题讨论】:

    标签: javascript reactjs redux react-redux reselect


    【解决方案1】:

    更新:

    请参考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,则为 reducer)。例如,使用 createSelector 创建的选择器意外地重新计算可能会在每次更新时接收到一个新对象,无论它包含的值是否已更改。 createSelector 使用身份检查 (===) 来检测输入是否已更改,因此在每次更新时返回一个新对象意味着选择器将在每次更新时重新计算。

    【讨论】:

    • 谢谢@Jordan。但是为什么在我的第二个例子中它没有重新计算?我也每次都创建一个新数组。唯一的区别是第一个例子除了一个输入,而第二个没有。我错过了什么?
    • 不客气。请参考我更新的答案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多