Skip to content

Commit

Permalink
fix(suspense): reset query status when error is thrown in suspense
Browse files Browse the repository at this point in the history
Fixes #468
  • Loading branch information
tannerlinsley committed May 11, 2020
1 parent b02f8dd commit c82a828
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"prettier": "^1.19.1",
"react": "^16.13.0",
"react-dom": "^16.13.0",
"react-error-boundary": "^2.2.1",
"rollup": "^1.32.0",
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-commonjs": "^10.0.0",
Expand Down
5 changes: 5 additions & 0 deletions src/tests/useMutation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ describe('useMutation', () => {
})

it('should be able to reset `error`', async () => {
jest.spyOn(console, 'error')
console.error.mockImplementation(() => {})

function Page() {
const [mutate, mutationResult] = useMutation(
() => {
Expand Down Expand Up @@ -82,5 +85,7 @@ describe('useMutation', () => {
fireEvent.click(getByText('reset'))

expect(queryByTestId('error')).toBeNull()

console.error.mockRestore()
})
})
64 changes: 64 additions & 0 deletions src/tests/useQuery.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { render, act, waitForElement, fireEvent } from '@testing-library/react'
import { ErrorBoundary } from 'react-error-boundary'
import * as React from 'react'

import { useQuery, queryCache } from '../index'
Expand Down Expand Up @@ -806,4 +807,67 @@ describe('useQuery', () => {
expect(queryFn).toHaveBeenCalledTimes(2)
expect(memoFn).toHaveBeenCalledTimes(2)
})

// https://github.com/tannerlinsley/react-query/issues/468
it('should reset error state if new component instances are mounted', async () => {
let succeed = false
const mockError = jest.fn()
jest.spyOn(console, 'error')
console.error.mockImplementation(mockError)

function Page() {
useQuery(
'test',
async () => {
await sleep(10)

if (!succeed) {
throw new Error()
} else {
return 'data'
}
},
{
retryDelay: 10,
suspense: true,
}
)

return <div>rendered</div>
}

const rendered = render(
<ErrorBoundary
fallbackRender={({ resetErrorBoundary }) => (
<div>
<div>error boundary</div>
<button
onClick={() => {
succeed = true
// Uncomment below and it will work
// queryCache.clear();
resetErrorBoundary()
}}
>
retry
</button>
</div>
)}
>
<React.Suspense fallback={'Loading...'}>
<Page />
</React.Suspense>
</ErrorBoundary>
)

await waitForElement(() => rendered.getByText('error boundary'))

expect(mockError).toHaveBeenCalledTimes(3)

fireEvent.click(rendered.getByText('retry'))

await waitForElement(() => rendered.getByText('rendered'))

console.error.mockRestore()
})
})
3 changes: 3 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ export function useMountedCallback(callback) {
export function handleSuspense(queryInfo) {
if (queryInfo.config.suspense || queryInfo.config.useErrorBoundary) {
if (queryInfo.status === statusError) {
setTimeout(() => {
queryInfo.query.state.status = 'loading'
})
throw queryInfo.error
}
}
Expand Down
19 changes: 19 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1514,6 +1514,13 @@
dependencies:
regenerator-runtime "^0.13.2"

"@babel/runtime@^7.9.6":
version "7.9.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f"
integrity sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==
dependencies:
regenerator-runtime "^0.13.4"

"@babel/template@^7.1.0", "@babel/template@^7.4.4", "@babel/template@^7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6"
Expand Down Expand Up @@ -5994,6 +6001,13 @@ react-dom@^16.13.0:
prop-types "^15.6.2"
scheduler "^0.19.0"

react-error-boundary@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-2.2.1.tgz#32ed74386a90482060cc2fea948bb7135465c4cb"
integrity sha512-8SZMkJRFUb0JuluHKwuUtkh5vvVWBg3O/bJIWgNMhMJv529aG//TmcphR3cSMhCWjz1vFZDb4taJd6pmwP5mEQ==
dependencies:
"@babel/runtime" "^7.9.6"

react-is@^16.8.1:
version "16.11.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.11.0.tgz#b85dfecd48ad1ce469ff558a882ca8e8313928fa"
Expand Down Expand Up @@ -6084,6 +6098,11 @@ regenerator-runtime@^0.13.2:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5"
integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==

regenerator-runtime@^0.13.4:
version "0.13.5"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"
integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==

regenerator-transform@^0.14.0:
version "0.14.1"
resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb"
Expand Down

0 comments on commit c82a828

Please sign in to comment.