Weird results when keepPreviousData is used with transitions
Describe the bug
Sandbox link
When I click decrease (in the second part of the example), I get unexpected results on example 2.2; Because other suspense boundaries depend on the same state, useQuery waits for them to render and only starts fetching after transition is complete. Can somebody explain why we get this result?
If i remove other two Suspense boundaries, everything seems normal. With keepPreviousData on, it starts fetching only when transition is complete, not sure if it's bug
One more strange thing I noticed is fetching triggered by refetchOnWindowFocus doesn't cause fallback in suspense? Is it right behavior?
Your minimal, reproducible example
https://codesandbox.io/s/funny-leftpad-wf7kbz?file=/src/App.js
Steps to reproduce
Click decrease: See that full update requires 10 seconds instead of 5.
Expected behaviour
- I expected 2.2 to work similarly with 2.1 in sandbox
- I expect refetchOnWindowFocus trigger fallback when used with suspense: true and current behaviour can be opt in using useDeferredValue or keepPreviousValue
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
Mac OS Monterey Latest Edge
react-query version
4.0.0-beta.7
TypeScript version
No response
Additional context
No response
I moved this from discussions because I believe at least one is a bug. https://github.com/tannerlinsley/react-query/discussions/3567
One more strange thing I noticed is fetching triggered by refetchOnWindowFocus doesn't cause fallback in suspense? Is it right behavior?
This is on purpose because suspense replaces a "hard loading state" where we have no data yet. For background refetches, the stale data is shown and the query will stay in success state.
I have looked at the sandbox, but I honestly have no idea why this is happening. It looks like a bug, but I would appreciate some help.
Thought about this a bit: keepPreviousData becomes unnecessary when you use suspense + startTransition. The screen will be kept in tact while the transition is going on. If we just remove keepPreviousData from your example, it works as expected.
keepPreviousData is meant to give you the "suspense" experience without actually using suspense.
The same issue seems to occur though with:
placeholderData: () => "fallback" + Math.random()
I'll close this issue for staleness and because I don't think there is something we can / should do. keepPreviousData doesn't make sense with suspense, and we might create a new hook especially for suspense like useSuspenseQuery, and in this case, it won't have the keepPreviousData / placeholderData option, because those won't do anything while suspending anyways.