Skip to content

Commit

Permalink
throw promise when key is falsy in suspense
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi committed May 7, 2020
1 parent 3b25d02 commit 601fe3e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 24 deletions.
13 changes: 9 additions & 4 deletions src/use-swr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ function useSWR<Data = any, Error = any>(

// update the state if the key changed (not the inital render) or cache updated
if (
(keyRef.current !== key && (!keyRef.current && !key)) ||
keyRef.current !== key ||
!config.compare(currentHookData, latestKeyedData)
) {
dispatch({ data: latestKeyedData })
Expand Down Expand Up @@ -543,10 +543,15 @@ function useSWR<Data = any, Error = any>(
typeof latestError === 'undefined'
) {
// need to start the request if it hasn't

if (!CONCURRENT_PROMISES[key]) {
// trigger revalidate immediately
// to get the promise
revalidate()
if (key) {
// trigger revalidate immediately
// to get the promise
revalidate()
} else {
throw Promise.reject()
}
}

if (
Expand Down
53 changes: 33 additions & 20 deletions test/use-swr.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1270,36 +1270,49 @@ describe('useSWR - suspense', () => {

// hold render when suspense
it('should pause when key is falsy', async () => {
const renderedResults = []

function Section() {
const [key, setKey] = useState(null)
function SectionContent({ swrKey, onClick }) {
const { data } = useSWR(
key,
k => new Promise(res => setTimeout(() => res(k), 50)),
() => (swrKey % 2 === 0 ? null : swrKey),
k => new Promise(res => setTimeout(() => res(k), 30)),
{
suspense: true
}
)

useEffect(() => {
setKey('suspense-9')
}, [])
return (
<div onClick={onClick}>
{swrKey && data ? 'suspense-' + (9 + Number(data)) : undefined}
</div>
)
}

if (data !== renderedResults[renderedResults.length - 1]) {
renderedResults.push(data)
}
const Section = () => {
const [key, setKey] = useState(0)
const handleClick = () => setKey(key + 1)

return <div>{data}</div>
return (
<Suspense fallback={<div onClick={handleClick}>fallback</div>}>
<SectionContent onClick={handleClick} swrKey={key} />
</Suspense>
)
}
render(
<Suspense fallback={<div>fallback</div>}>
<Section />
</Suspense>
)
await act(() => new Promise(res => setTimeout(res, 210)))

expect(renderedResults).toEqual(['suspense-9'])
const { container } = render(<Section />)

async function clickAndWait(duration) {
fireEvent.click(container.firstElementChild)
return await act(
() => new Promise(resolve => setTimeout(resolve, duration))
)
}

expect(container.textContent).toMatchInlineSnapshot(`"fallback"`)
await clickAndWait(100)
expect(container.textContent).toMatchInlineSnapshot(`"suspense-10"`)
await clickAndWait(100)
expect(container.textContent).toMatchInlineSnapshot(`"fallback"`)
await clickAndWait(100)
expect(container.textContent).toMatchInlineSnapshot(`"suspense-10"`)
})
})

Expand Down

0 comments on commit 601fe3e

Please sign in to comment.