Reselect - how to figure out which argument changed?
Asked Answered
B

3

6

Selectors are efficient. A selector is not recomputed unless one of its arguments changes.

I'm trying to debug a selector that is being called more often than expected. Is there a way to log why a particular selector was recomputed (i. e. which argument changed)?

Example:

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

Now let's say that the return value of totalSelector is supplied to some component as a result prop via mapStateToProps. why-did-you-render reports unnecessary render due to changing reference (not value) of result. Therefore I know totalSelector must have been recomputed and we know from the docs that it only happens when of its inputs change (subtotal or tax in the example). How can I tell whether it was subtotal that triggered a change or tax or both?

For the purpose of this explanation let's assume both subtotal and tax are objects, so they are passed by reference.

Brentwood answered 17/12, 2019 at 14:29 Comment(2)
You need to add more detail e.g. your selector code and model.Peripatetic
@BenSmith example and further explanation providedBrentwood
M
0

One thing that helped me in my situation is to put a breakpoint at this line so that you can clearly see the argument that is causing the recomputation.

Mannerism answered 1/11, 2021 at 19:52 Comment(0)
I
3

Here's a simple drop-in replacement for createSelector which will log the first changed param value:

const createDebugSelector = createSelectorCreator(defaultMemoize, {
  equalityCheck: (previousVal, currentVal) => {
    const rv = currentVal === previousVal;
    if (!rv) console.log('Selector param value changed', currentVal);
    return rv;
  },
});
Inextensible answered 22/12, 2021 at 16:48 Comment(0)
M
0

One thing that helped me in my situation is to put a breakpoint at this line so that you can clearly see the argument that is causing the recomputation.

Mannerism answered 1/11, 2021 at 19:52 Comment(0)
C
-1

You should check this tool out: https://github.com/welldone-software/why-did-you-render

Put it on the component (the one wrapped in connect) and it will tell you which props are deep equal but not shallow equal.

Corporative answered 17/12, 2019 at 14:36 Comment(4)
I'm using this tool, on the component level it does a great job. So I know that a particular selector got recomputed. What I want to know is why it was recomputed.Brentwood
His blog posts actually have great descriptions of the problems and potential fixes: medium.com/welldone-software/…. If you post the code of your selector I may be able to help moreCorporative
example provided, it's not really about the selector implementation though.Brentwood
Maybe you can do something like this to debug: codesandbox.io/s/clever-faraday-jw99j. Create a custom createSelector where you log out the values and if they are equal or notCorporative

© 2022 - 2025 — McMap. All rights reserved.