重新选择 - 如何确定哪个参数发生了变化?

Posted

技术标签:

【中文标题】重新选择 - 如何确定哪个参数发生了变化?【英文标题】:Reselect - how to figure out which argument changed? 【发布时间】:2020-04-10 02:00:07 【问题描述】:

选择器是有效的。除非其中一个参数发生变化,否则不会重新计算选择器。

我正在尝试调试比预期更频繁地调用的选择器。有没有办法记录重新计算特定选择器的原因(即更改了哪个参数)?

例子:

export const totalSelector = createSelector(
  [subtotalSelector, taxSelector]
  (subtotal, tax) => ( total: someExpensiveCalculation(subtotal, tax) )
)

现在假设totalSelector 的返回值作为result 属性通过mapStateToProps 提供给某个组件。 why-did-you-render 报告由于 result 的引用(而非值)更改而导致不必要的渲染。因此,我知道totalSelector 必须已重新计算,并且我们从文档中知道它仅在其输入更改时发生(示例中为subtotaltax)。我如何判断是subtotal 触发了更改还是tax 或两者兼而有之?

为了便于解释,我们假设 subtotaltax 都是对象,因此它们是通过引用传递的。

【问题讨论】:

您需要添加更多细节,例如你的选择器代码和模型。 @BenSmith 示例并提供进一步解释 【参考方案1】:

在我的情况下帮助我的一件事是在 line 处放置一个断点,以便您可以清楚地看到导致重新计算的参数。

【讨论】:

【参考方案2】:

你应该看看这个工具:https://github.com/welldone-software/why-did-you-render

把它放在组件上(用 connect 包裹的那个),它会告诉你哪些 props 是深相等但不是浅层相等。

【讨论】:

我正在使用这个工具,在组件级别它做得很好。所以我知道一个特定的选择器被重新计算了。我想知道的是为什么要重新计算。 他的博客文章实际上对问题和潜在修复有很好的描述:medium.com/welldone-software/…。如果您发布选择器的代码,我可能会提供更多帮助 提供了示例,但实际上并不是关于选择器的实现。 也许你可以做这样的事情来调试:codesandbox.io/s/clever-faraday-jw99j。创建一个自定义 createSelector,您可以在其中注销值以及它们是否相等【参考方案3】:

这是createSelector 的简单替换,它将记录第一个更改的参数值:

const createDebugSelector = createSelectorCreator(defaultMemoize, 
  equalityCheck: (previousVal, currentVal) => 
    const rv = currentVal === previousVal;
    if (!rv) console.log('Selector param value changed', currentVal);
    return rv;
  ,
);

【讨论】:

以上是关于重新选择 - 如何确定哪个参数发生了变化?的主要内容,如果未能解决你的问题,请参考以下文章

Android 如何检测更改了哪个联系人?

打开图像并使用相同的参数重新保存它,c#

你假笨JVM参数 - 1 CMSScavengeBeforeRemark

当参数数量可能发生变化时,如何编写 OR 查询?

Selenium - CSS选择器:如何在每个项目的长项列表中找出哪个颜色是选择器?

Hyperopt:重新运行时更改最佳参数