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

feat: add equality fn to atomWithQuery #386

Merged
merged 2 commits into from
Mar 31, 2021

Conversation

aulneau
Copy link
Collaborator

@aulneau aulneau commented Mar 27, 2021

This takes the same equalityFn signature from selectAtom and adds it to the atomWithQuery helper. I have found this very helpful in my apps to help control rerenders while the query revalidates. Currently, if the query is set to refetch on an interval, when it sets the data atom again it will cause any component that uses the data to rerender even if nothing in the data has changed.

Happy to explore other options, but this works for me currently.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Mar 27, 2021

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 965db9b:

Sandbox Source
React Configuration
React Typescript Configuration

@dai-shi
Copy link
Member

dai-shi commented Mar 27, 2021

As we discussed in discord, I'm not a big fan of equalityFn. But, this sounds unavoidable.

Currently, if the query is set to refetch on an interval, when it sets the data atom again it will cause any component that uses the data to rerender even if nothing in the data has changed.

As this means, react-query returns an different object with the same content.

Comment on lines 64 to 70
const data = get(dataAtom)
if (!data || !equalityFn(data, action.data)) {
set(dataAtom, action.data)
}
const pending = get(pendingAtom)
if (!pending.fulfilled) {
pending.resolve(action.data)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably better to keep the pair of dataAtom and pendingAtom in sync.

Suggested change
const data = get(dataAtom)
if (!data || !equalityFn(data, action.data)) {
set(dataAtom, action.data)
}
const pending = get(pendingAtom)
if (!pending.fulfilled) {
pending.resolve(action.data)
const data = get(dataAtom)
if (!data || !equalityFn(data, action.data)) {
set(dataAtom, action.data)
const pending = get(pendingAtom)
if (!pending.fulfilled) {
pending.resolve(action.data)
}

@@ -60,7 +61,10 @@ export function atomWithQuery<
}
action.initializer(getQueryClient(get, set))
} else if (action.type === 'data') {
set(dataAtom, action.data)
const data = get(dataAtom)
if (!data || !equalityFn(data, action.data)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!data || !equalityFn(data, action.data)) {
if (data === null || !equalityFn(data, action.data)) {

Let's make it strict here. (tbh, i'm not certain if null in L37 is valid to mean uninitialized. Can TData ever be null?)

@dai-shi
Copy link
Member

dai-shi commented Mar 27, 2021

@Aslemammad thoughts?

@aulneau
Copy link
Collaborator Author

aulneau commented Mar 28, 2021

As this means, react-query returns an different object with the same content.

Yeah, I think it does. I know they have this feature: notifyOnChangeProps however when I have tried to enable it, it breaks completely 🤷

Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Would you like to add a note about equalityFn in docs?

@dai-shi
Copy link
Member

dai-shi commented Mar 31, 2021

Merging this now.
Please open follow-up PRs to improve docs.

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.

2 participants