Skip to content

Commit

Permalink
feat: add a warning for invalid arguments with suspense mode (#1402)
Browse files Browse the repository at this point in the history
  • Loading branch information
koba04 committed Aug 29, 2021
1 parent 321a0c1 commit c703e6c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/use-swr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ export const useSWRHandler = <Data = any, Error = any>(
const data = isUndefined(cached) ? fallback : cached
const error = cache.get(keyErr)

if (suspense && (!key || !fn)) {
throw new Error('useSWR requires either key or fetcher with suspense mode')
}

// A revalidation must be triggered when mounted if:
// - `revalidateOnMount` is explicitly set to `true`.
// - Suspense mode and there's stale data for the initial render.
Expand Down
53 changes: 48 additions & 5 deletions test/use-swr-suspense.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ import React, { ReactNode, Suspense, useEffect, useState } from 'react'
import useSWR, { mutate } from 'swr'
import { createResponse, sleep } from './utils'

class ErrorBoundary extends React.Component<{ fallback: ReactNode }> {
state = { hasError: false }
static getDerivedStateFromError() {
class ErrorBoundary extends React.Component<{ fallback?: ReactNode }> {
state = { hasError: false, message: null }
static getDerivedStateFromError(error: Error) {
return {
hasError: true
hasError: true,
message: error.message
}
}
render() {
if (this.state.hasError) {
return this.props.fallback
return this.props.fallback || this.state.message
}
return this.props.children
}
Expand Down Expand Up @@ -258,4 +259,46 @@ describe('useSWR - suspense', () => {
expect(startRenderCount).toBe(2) // fallback + data
expect(renderCount).toBe(1) // data
})

it('should throw an error if key is a falsy value', async () => {
// eslint-disable-next-line @typescript-eslint/no-empty-function
jest.spyOn(console, 'error').mockImplementation(() => {})

function Page() {
const { data } = useSWR(null, () => createResponse('SWR'), {
suspense: true
})
return <div>hello, {data}</div>
}
render(
<ErrorBoundary>
<Suspense fallback={<div>fallback</div>}>
<Page />
</Suspense>
</ErrorBoundary>
)

screen.getByText('useSWR requires either key or fetcher with suspense mode')
})

it('should throw an error if fetch is null', async () => {
// eslint-disable-next-line @typescript-eslint/no-empty-function
jest.spyOn(console, 'error').mockImplementation(() => {})

function Page() {
const { data } = useSWR('suspense-11', null, {
suspense: true
})
return <div>hello, {data}</div>
}
render(
<ErrorBoundary>
<Suspense fallback={<div>fallback</div>}>
<Page />
</Suspense>
</ErrorBoundary>
)

screen.getByText('useSWR requires either key or fetcher with suspense mode')
})
})

0 comments on commit c703e6c

Please sign in to comment.