Skip to content

Commit

Permalink
fix(core): change shouldFetchOptionally condition
Browse files Browse the repository at this point in the history
Change this condition to not change the status of result to 'loading'
when state.status is 'error'

Fixes #2187
  • Loading branch information
JaeYeopHan committed Aug 10, 2021
1 parent 6bbb371 commit b5686c2
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/core/queryObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@ function shouldFetchOptionally(
return (
options.enabled !== false &&
(query !== prevQuery || prevOptions.enabled === false) &&
query.state.status !== 'error' &&
isStale(query, options)
)
}
Expand Down
70 changes: 70 additions & 0 deletions src/react/tests/suspense.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -577,4 +577,74 @@ describe("useQuery's in Suspense mode", () => {
expect(queryFn).toHaveBeenCalledTimes(1)
await waitFor(() => rendered.getByLabelText('fire'))
})

it('should error catched in error boundary without infinite loop', async () => {
const key = queryKey()

const consoleMock = mockConsoleError()

let succeed = true

function Page() {
const [nonce] = React.useState(0)
const queryKeys = `${key}-${succeed}`
const result = useQuery(
queryKeys,
async () => {
await sleep(100)
if (!succeed) {
throw new Error('Suspense Error Bingo')
} else {
return nonce
}
},
{
retry: false,
suspense: true,
}
)
return (
<div>
<span>rendered</span> <span>{result.data}</span>
<button
aria-label="fail"
onClick={async () => {
await queryClient.resetQueries()
}}
>
fail
</button>
</div>
)
}

function App() {
const { reset } = useQueryErrorResetBoundary()
return (
<ErrorBoundary
onReset={reset}
fallbackRender={() => <div>error boundary</div>}
>
<React.Suspense fallback="Loading...">
<Page />
</React.Suspense>
</ErrorBoundary>
)
}

const rendered = renderWithClient(queryClient, <App />)

// render suspense fallback (Loading...)
await waitFor(() => rendered.getByText('Loading...'))
// resolve promise -> render Page (rendered)
await waitFor(() => rendered.getByText('rendered'))

// change query key
succeed = false
// reset query -> and throw error
fireEvent.click(rendered.getByLabelText('fail'))
// render error boundary fallback (error boundary)
await waitFor(() => rendered.getByText('error boundary'), { timeout: 500 })
consoleMock.mockRestore()
})
})

0 comments on commit b5686c2

Please sign in to comment.