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(query): subscribe instead of fetch if initialData #586

Merged
merged 3 commits into from
Jul 14, 2021

Conversation

aulneau
Copy link
Collaborator

@aulneau aulneau commented Jul 9, 2021

While doing some more testing, I noticed that on mount a query would automatically refetch even though I had provided initialData to it. I could not stop this behavior -- based off of reading https://react-query.tanstack.com/guides/initial-query-data#_top, it is the case that initialData will be treated as fresh until the staleTime has been met, or based on other user options passed (meaning a fetch should not happen until it become stale, and there have been some refetch options passed)

Because we were automatically running the fetchOptimistic method regardless of if initialData was passed, we were causing an unneeded fetch to happen. React query will pick up and take over and do all the fetching if needed when there is initialData. We are already subscribing on mount, so there is no need to fetch during the initial get.

@aulneau aulneau requested a review from dai-shi July 9, 2021 15:56
@vercel
Copy link

vercel bot commented Jul 9, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/pmndrs/jotai/45V3uyoqf5pbyiV4LG2wkzEz3iqv
✅ Preview: https://jotai-git-fix-query-no-need-to-fetch-pmndrs.vercel.app

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jul 9, 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 ab36eaa:

Sandbox Source
React Configuration
React Typescript Configuration

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.

The approach seems valid: if we don't store the initial promise, it will mount, so fetchOptimistic is not required.
Is it possible to add failing tests? I'm not super confident to keep the behavior when we do some refactors.

.fetchOptimistic(defaultedOptions)
.then(listener)
.catch((error) => listener({ error }))
if (!defaultedOptions.initialData) {
Copy link
Member

Choose a reason for hiding this comment

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

More precisely, you want to check if getInitialData() returns non-falsy value. Like, options.initialData = () => null. We may drop the support of it. Just needs to make it consistent.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure, that is a good catch. Do you think this would be sufficient?

Suggested change
if (!defaultedOptions.initialData) {
if (!getInitialData()) {

Copy link
Member

Choose a reason for hiding this comment

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

I think we should call getInitialData() just once in our code.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yep, agreed!

@@ -301,5 +302,7 @@ it('query with initialData test', async () => {

// NOTE: the atom never suspends
await findByText('count: 0')
expect(mockFetch).toHaveBeenCalledTimes(0)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@dai-shi does this work for you with regards to testing? I can't think immediately a way to create a failing test

Copy link
Member

Choose a reason for hiding this comment

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

Do you mean this doesn't fail before the fix?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ah i see what you mean, yes it does fail:

Screen Shot 2021-07-09 at 6 41 09 PM

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.

Thanks for the change. It looks good to me.

Is anyone else interested in trying and/or reviewing?

Comment on lines +127 to +130
observer
.fetchOptimistic(defaultedOptions)
.then(listener)
.catch((error) => listener({ error }))
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@dai-shi I don't think we need this bit of code either way it seems -- can you tell me more about it?

Because we are subscribing on mount, the subscription kicks off the fetch initially. Seems like we're doing double work, unless I am missing something

Copy link
Member

Choose a reason for hiding this comment

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

When an atom suspends, the component suspends and it will not be mounted, which means onMount will not be called. Unless we resolve the promise, the component will not be mounted.

@dai-shi dai-shi merged commit a9cb873 into master Jul 14, 2021
@dai-shi dai-shi deleted the fix/query-no-need-to-fetch branch July 14, 2021 23:46
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