Describe the bug
When useQuery is added to a component, that component experiences multiple renders with the same content.
To Reproduce
I am using this component to test:
import React from "react";
import { useQuery } from "react-query";
const myQuery = () =>
new Promise(resolve => {
setTimeout(resolve, 500, "SUCCESS");
});
export const Test = () => {
const { isLoading, error, data } = useQuery("myquery", myQuery);
console.log({ isLoading, error, data });
return <div>Test</div>;
};
Expected behavior
I expected to see in the logs:
{ isLoading: true, error: null, data: undefined }
{ isLoading: false, error: null, data: "SUCCESS" }
Actual Behavior
Instead, what I saw in the logs:
{ isLoading: true, error: null, data: undefined }
{ isLoading: true, error: null, data: undefined }
{ isLoading: false, error: null, data: "SUCCESS" }
{ isLoading: false, error: null, data: "SUCCESS" }
Additional context
It seems like the component is rendering twice as much as it should be.
I converted the code to use this instead:
const everything = useQuery("myquery", myQuery);
console.log(JSON.stringify(everything));
and it seems like there are changes in the return from useQuery.
Most notably is the instances, which is an empty array and then the 2nd render becomes:
[
{
id: 0,
config: {
suspense: false,
enabled: true,
retry: 3,
staleTime: 0,
cacheTime: 300000,
refetchOnWindowFocus: false,
refetchInterval: false,
refetchOnMount: true,
useErrorBoundary: false
}
}
]
There are also added props in the 2nd render:
cancelled: null,
promise: {}
So it looks like these multiple renders are as designed.
Anyone more familiar have some additional comments on this behavior that could help my understanding?
Hello @joelnet
that's definitely rerendering 2 times in development, maybe you trying to build to production so the second rendering will be not appears
Hey @joelnet
I was able to replicate this on codesandbox: https://codesandbox.io/s/keen-hellman-xxyto?file=/src/App.js
And after removing strict mode from react, it solves the problem: https://codesandbox.io/s/hungry-lovelace-ig44s?file=/src/App.js
StrictMode renders components twice (on dev but not production) in order to detect any problems with your code and warn you about them (which can be quite useful).
If you have StrictMode enabled in your app but don't remember enabling it, it might be because you used create-react-app or similar to create your app initially, which automatically enables StrictMode by default.
This behaviour is documented: https://reactjs.org/docs/strict-mode.html
Note:
This only applies to development mode. Lifecycles will not be double-invoked in production mode.
Sorry it took so long to get back. It took me a lot of debugging and trial and error.
Hello @joelnet
that's definitely rerendering 2 times in development, maybe you trying to build to production so the second rendering will be not appears
I was able to confirm that this was not my issue. I could run a production build with NODE_ENV=production webpack --mode production and then serve it with npx serve dist. The issue still persisted.
Hey @joelnet
I was able to replicate this on codesandbox: https://codesandbox.io/s/keen-hellman-xxyto?file=/src/App.js
And after removing strict mode from react, it solves the problem: https://codesandbox.io/s/hungry-lovelace-ig44s?file=/src/App.jsStrictMode renders components twice (on dev but not production) in order to detect any problems with your code and warn you about them (which can be quite useful).
If you have StrictMode enabled in your app but don't remember enabling it, it might be because you used create-react-app or similar to create your app initially, which automatically enables StrictMode by default.
Your codesandbox was very helpful, but this was also not my issue as the setup was done manually (no CRA) and StrictMode was not present.
Eventually, I created a new empty project and useQuery worked correctly. So I started to copy things one by one from the broken project into the working project. Until everything was copied and the project never broke. So now I am really confused.
As a last resort I ran:
rm -rf node_modules package-lock.json
npm install
And it magically started working as expected.
In the end I never found the actual cause. Some outdated dependency? I'll never know.
Thanks to @adibfirman, @PierreAndreis, and @montogeek. I assumed this was expected behavior. So without showing me that it should not behave that way, I would not have spent so much time investigating this.
TL;DR There was a problem with either my node_modules or package-lock.json. I deleted them and reinstalled dependencies.
¯\_(ツ)_/¯
@joelnet thanks for this issue. The same thing was happening to me - component rendered twice with the same data if useQuery was used.
Don't know what was the reason but
rm -rf node_modules package-lock.json
npm install
helped!!!
Most helpful comment
Sorry it took so long to get back. It took me a lot of debugging and trial and error.
I was able to confirm that this was not my issue. I could run a production build with
NODE_ENV=production webpack --mode productionand then serve it withnpx serve dist. The issue still persisted.Your codesandbox was very helpful, but this was also not my issue as the setup was done manually (no CRA) and StrictMode was not present.
Eventually, I created a new empty project and
useQueryworked correctly. So I started to copy things one by one from the broken project into the working project. Until everything was copied and the project never broke. So now I am really confused.As a last resort I ran:
And it magically started working as expected.
In the end I never found the actual cause. Some outdated dependency? I'll never know.
Thanks to @adibfirman, @PierreAndreis, and @montogeek. I assumed this was expected behavior. So without showing me that it should not behave that way, I would not have spent so much time investigating this.
TL;DR There was a problem with either my
node_modulesorpackage-lock.json. I deleted them and reinstalled dependencies.¯\_(ツ)_/¯