Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(component-store): fix memoization not working when passing selectors directly to select #3356

Merged
merged 1 commit into from
Mar 28, 2022

Conversation

P4
Copy link
Contributor

@P4 P4 commented Mar 25, 2022

This makes selectors created with createSelector usable with ComponentStore.select
which looks like it should work, but would previously result in the selector getting recomputed each time.

When select method is called with a single argument, the projector function was being passed directly to map, which invokes its callback with an extra index argument. This is basically the same problem as the JS gotcha where [1,2,3].map(parseInt) returns [1, NaN, NaN].

Because the value of index is different each time, the memoized selector would get invalidated even if the actual state remained exactly the same.

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

[x] Bugfix
[ ] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Documentation content changes
[ ] Other... Please describe:

What is the current behavior?

Given

const memoizedSelector = createSelector(...)

passing it to a component store directly

componentStore.select(memoizedSelector)

results in the selector being re-computed on each store update, even if the state does not actually change.

The memoization works fine again if the selector is wrapped inside an extra function:

componentStore.select(state => memoizedSelector(state))

What is the new behavior?

Both usages of select() shown above should now work the same way.

Does this PR introduce a breaking change?

[ ] Yes
[x] No

Other information

@netlify
Copy link

netlify bot commented Mar 25, 2022

Deploy Preview for ngrx-io canceled.

Built without sensitive environment variables

Name Link
🔨 Latest commit 1866f8b
🔍 Latest deploy log https://app.netlify.com/sites/ngrx-io/deploys/623f614b49a7e800093e2956

…ors directly to select

Make selectors created with `createSelector` usable with `ComponentStore.select`
which looks like it should work, but would previously result in the selector getting recomputed each time.

When select method is called with a single argument, the projector function was being passed directly to `map`,
which invokes its callback with an extra `index` argument. Because the value of index is always different,
the memoized selector would get invalidated even if the actual state remained exactly the same.
@timdeschryver timdeschryver merged commit 38bce88 into ngrx:master Mar 28, 2022
@timdeschryver
Copy link
Member

Thanks @P4 ! 🏆

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants