Skip to content

Commit 8c70c34

Browse files
icyJosephnevilm-lt
authored andcommitted
fix: Return undefined data if key's falsy under suspense mode (vercel#1698)
1 parent 00c4741 commit 8c70c34

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

src/use-swr.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ export const useSWRHandler = <Data = any, Error = any>(
498498
// If there is `error`, the `error` needs to be thrown to the error boundary.
499499
// If there is no `error`, the `revalidation` promise needs to be thrown to
500500
// the suspense boundary.
501-
if (suspense && isUndefined(data)) {
501+
if (suspense && isUndefined(data) && key) {
502502
throw isUndefined(error) ? revalidate(WITH_DEDUPE) : error
503503
}
504504

test/use-swr-config.test.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
import { act, screen, fireEvent } from '@testing-library/react'
22
import React, { useEffect, useState } from 'react'
33
import useSWR, { SWRConfig, useSWRConfig, Middleware } from 'swr'
4-
import {
5-
sleep,
6-
renderWithConfig,
7-
createKey,
8-
renderWithGlobalCache
9-
} from './utils'
4+
import { renderWithConfig, createKey, renderWithGlobalCache } from './utils'
105

116
describe('useSWR - configs', () => {
127
it('should read the config fallback from the context', async () => {
@@ -30,8 +25,7 @@ describe('useSWR - configs', () => {
3025
await screen.findByText('data: 0')
3126

3227
// wait for the refresh interval
33-
await act(() => sleep(INTERVAL * 1.5))
34-
screen.getByText('data: 1')
28+
await screen.findByText('data: 1')
3529
})
3630

3731
it('should stop revalidations when config.isPaused returns true', async () => {

test/use-swr-suspense.test.tsx

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { act, fireEvent, screen } from '@testing-library/react'
2-
import React, { ReactNode, Suspense, useEffect, useState } from 'react'
2+
import React, {
3+
ReactNode,
4+
Suspense,
5+
useEffect,
6+
useReducer,
7+
useState
8+
} from 'react'
39
import useSWR, { mutate } from 'swr'
410
import {
511
createKey,
@@ -274,4 +280,40 @@ describe('useSWR - suspense', () => {
274280
expect(startRenderCount).toBe(2) // fallback + data
275281
expect(renderCount).toBe(1) // data
276282
})
283+
284+
it('should return `undefined` data for falsy key', async () => {
285+
const key = createKey()
286+
const Section = ({ trigger }: { trigger: boolean }) => {
287+
const { data } = useSWR(
288+
trigger ? key : null,
289+
() => createResponse('SWR'),
290+
{
291+
suspense: true
292+
}
293+
)
294+
return <div>{data || 'empty'}</div>
295+
}
296+
297+
const App = () => {
298+
const [trigger, toggle] = useReducer(x => !x, false)
299+
return (
300+
<div>
301+
<button onClick={toggle}>toggle</button>
302+
<Suspense fallback={<div>fallback</div>}>
303+
<Section trigger={trigger} />
304+
</Suspense>
305+
</div>
306+
)
307+
}
308+
309+
renderWithConfig(<App />)
310+
311+
await screen.findByText('empty')
312+
313+
fireEvent.click(screen.getByRole('button'))
314+
315+
screen.getByText('fallback')
316+
317+
await screen.findByText('SWR')
318+
})
277319
})

0 commit comments

Comments
 (0)