Skip to content

Commit 360d38c

Browse files
committed
fix: only trigger suspense when loading for the first time
1 parent c47f415 commit 360d38c

File tree

3 files changed

+79
-7
lines changed

3 files changed

+79
-7
lines changed

src/core/queryObserver.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,25 @@ export class QueryObserver<
9292
}
9393
}
9494

95-
willFetchOnMount(): boolean {
95+
willLoadOnMount(): boolean {
96+
return (
97+
this.options.enabled !== false && !this.currentQuery.state.dataUpdatedAt
98+
)
99+
}
100+
101+
willRefetchOnMount(): boolean {
96102
return (
97103
this.options.enabled !== false &&
98-
(!this.currentQuery.state.dataUpdatedAt ||
99-
this.options.refetchOnMount === 'always' ||
104+
this.currentQuery.state.dataUpdatedAt > 0 &&
105+
(this.options.refetchOnMount === 'always' ||
100106
(this.options.refetchOnMount !== false && this.isStale()))
101107
)
102108
}
103109

110+
willFetchOnMount(): boolean {
111+
return this.willLoadOnMount() || this.willRefetchOnMount()
112+
}
113+
104114
willFetchOnReconnect(): boolean {
105115
return (
106116
this.options.enabled !== false &&

src/react/tests/suspense.test.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,64 @@ describe("useQuery's in Suspense mode", () => {
275275
consoleMock.mockRestore()
276276
})
277277

278+
it('should refetch when re-mounting', async () => {
279+
const key = queryKey()
280+
let count = 0
281+
282+
function Component() {
283+
const result = useQuery(
284+
key,
285+
async () => {
286+
await sleep(100)
287+
count++
288+
return count
289+
},
290+
{
291+
retry: false,
292+
suspense: true,
293+
staleTime: 0,
294+
}
295+
)
296+
return (
297+
<div>
298+
<span>data: {result.data}</span>
299+
<span>fetching: {result.isFetching ? 'true' : 'false'}</span>
300+
</div>
301+
)
302+
}
303+
304+
function Page() {
305+
const [show, setShow] = React.useState(true)
306+
return (
307+
<div>
308+
<button
309+
onClick={() => {
310+
setShow(!show)
311+
}}
312+
>
313+
{show ? 'hide' : 'show'}
314+
</button>
315+
<React.Suspense fallback="Loading...">
316+
{show && <Component />}
317+
</React.Suspense>
318+
</div>
319+
)
320+
}
321+
322+
const rendered = renderWithClient(queryClient, <Page />)
323+
324+
await waitFor(() => rendered.getByText('Loading...'))
325+
await waitFor(() => rendered.getByText('data: 1'))
326+
await waitFor(() => rendered.getByText('fetching: false'))
327+
await waitFor(() => rendered.getByText('hide'))
328+
fireEvent.click(rendered.getByText('hide'))
329+
await waitFor(() => rendered.getByText('show'))
330+
fireEvent.click(rendered.getByText('show'))
331+
await waitFor(() => rendered.getByText('fetching: true'))
332+
await waitFor(() => rendered.getByText('data: 2'))
333+
await waitFor(() => rendered.getByText('fetching: false'))
334+
})
335+
278336
it('should retry fetch if the reset error boundary has been reset with global hook', async () => {
279337
const key = queryKey()
280338

src/react/useBaseQuery.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,13 @@ export function useBaseQuery<TData, TError, TQueryFnData, TQueryData>(
3333
)
3434
}
3535

36-
// Always set stale time when using suspense
37-
if (defaultedOptions.suspense && !defaultedOptions.staleTime) {
38-
defaultedOptions.staleTime = 2000
36+
// Always set stale time when using suspense to prevent
37+
// fetching again when directly re-mounting after suspense
38+
if (
39+
defaultedOptions.suspense &&
40+
typeof defaultedOptions.staleTime !== 'number'
41+
) {
42+
defaultedOptions.staleTime = 1000
3943
}
4044

4145
// Create query observer
@@ -72,7 +76,7 @@ export function useBaseQuery<TData, TError, TQueryFnData, TQueryData>(
7276
if (
7377
observer.options.suspense &&
7478
!observer.hasListeners() &&
75-
observer.willFetchOnMount()
79+
observer.willLoadOnMount()
7680
) {
7781
errorResetBoundary.clearReset()
7882
const unsubscribe = observer.subscribe()

0 commit comments

Comments
 (0)