query: Add config option to fix bad UX with Next.js static pre-rendering.
Context
Next.js static pre-renders any page not doing SSR. During pre-rendering on the server, route parameters are empty (because there’s no request). For example, a dynamic page like /products/[productId].tsx will be rendered with query.productId === undefined.
Problem 1
useQuery will call the query function during pre-rendering, on the server, which will usually cause noisy but harmless error logs (but they are alarming if you don’t know exactly what’s happening here).
Workaround: If typeof window === 'undefined', pass a never resolving promise instead of the real query function.
Problem 2
Because the page was statically rendered with empty route params, Next.js will make the first render on the client also have empty route params (otherwise React complains). And it’s very common to use a route parameter with useQuery.
So now we have a problem because on the first render useQuery will call your query function which has invalid parameters (route parameter is undefined instead of string, for example). And so this causes noisy but harmless error logs (but they are alarming if you don’t know exactly what’s happening here).
Workaround: If the router is not ready, pass a never resolving promise instead of the real query function AND use a bogus query key.
You can see in the blitz code how we are currently using both workarounds.
Proposed Solution
At first glance, the enabled config flag seems like the answer. However, that doesn’t work because in concurrent mode, useQuery does not throw when enabled = false.
So we need a new config flag similar to enabled that let’s us disable the query function being called but while still throwing the loading promise.
Alternate solution: Change the current behavior so that useQuery always throws even if enabled = false.
Additional context
Earlier discussion about this problem: https://github.com/tannerlinsley/react-query/issues/744
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 2
- Comments: 15 (5 by maintainers)
What if you have two queries in a suspense component and one of them is conditional? If the conditional query would throw a never resolving promise, then the component would never render? Think the custom
useQueryhook is a pretty good solution 😃Let’s just have it suspend all the time then. Suspense is experimental so I’m not too concerned about it