-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Closed
Labels
Description
Describe the bug
The workaround in #2157 fixed only part of the issue we are having in Blitz. We still have a case on user logout where we get infinite loops.
Failing test case included below. They key thing that makes it go into the infinite loop is the query key changing. If the key doesn't change, then it works fine.
To Reproduce
Add the following test to src/react/tests/suspense.test.tsx
it('should not have infinite loop', async () => {
const key = queryKey()
const consoleMock = mockConsoleError()
let succeed = true
function Page() {
const [nonce] = React.useState(0)
const fullKey = `${key}-${succeed}`
const result = useQuery(
fullKey,
async () => {
await sleep(10)
console.log('query', fullKey)
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={({ resetErrorBoundary }) => (
<div>
<div>error boundary</div>
<button
onClick={() => {
resetErrorBoundary()
}}
>
retry
</button>
</div>
)}
>
<React.Suspense fallback="Loading...">
<Page />
</React.Suspense>
</ErrorBoundary>
)
}
const rendered = renderWithClient(queryClient, <App />)
await waitFor(() => rendered.getByText('Loading...'))
await waitFor(() => rendered.getByText('rendered'))
succeed = false
fireEvent.click(rendered.getByLabelText('fail'))
await waitFor(() => rendered.getByText('error boundary'))
consoleMock.mockRestore()
})Version
React-query 3.13.9
jbee37142benbender