Skip to content

Commit c30eda2

Browse files
authored
feat: pass arguments to onReset callback (#51)
1 parent 4e240df commit c30eda2

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,11 @@ state (which will result in rendering the `children` again). You should use this
273273
to ensure that re-rendering the children will not result in a repeat of the same
274274
error happening again.
275275

276+
`onReset` will be called with whatever `resetErrorBoundary` is called with. In
277+
the case of `resetKeys`, it's called with the `prevResetKeys` and the
278+
`resetKeys`. This can help you differentiate between a reset that occurred due
279+
to a "try again" button click and one trigged by a `resetKeys` change.
280+
276281
### `resetKeys`
277282

278283
Sometimes an error happens as a result of local state to the component that's

src/__tests__/index.js

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,14 +252,30 @@ test('requires either a fallback, fallbackRender, or FallbackComponent', () => {
252252
})
253253

254254
test('supports automatic reset of error boundary when resetKeys change', () => {
255+
const handleReset = jest.fn()
256+
const TRY_AGAIN_ARG1 = 'TRY_AGAIN_ARG1'
257+
const TRY_AGAIN_ARG2 = 'TRY_AGAIN_ARG2'
255258
function App() {
256259
const [explode, setExplode] = React.useState(false)
257260
return (
258261
<div>
259262
<button onClick={() => setExplode(e => !e)}>toggle explode</button>
260263
<ErrorBoundary
261-
FallbackComponent={ErrorFallback}
262-
onReset={() => setExplode(false)}
264+
fallbackRender={({resetErrorBoundary}) => (
265+
<div role="alert">
266+
<button
267+
onClick={() =>
268+
resetErrorBoundary(TRY_AGAIN_ARG1, TRY_AGAIN_ARG2)
269+
}
270+
>
271+
Try again
272+
</button>
273+
</div>
274+
)}
275+
onReset={(...args) => {
276+
setExplode(false)
277+
handleReset(...args)
278+
}}
263279
resetKeys={[explode]}
264280
>
265281
{explode ? <Bomb /> : null}
@@ -268,21 +284,32 @@ test('supports automatic reset of error boundary when resetKeys change', () => {
268284
)
269285
}
270286
render(<App />)
271-
userEvent.click(screen.getByText('toggle explode'))
272287

288+
// blow it up
289+
userEvent.click(screen.getByText('toggle explode'))
273290
screen.getByRole('alert')
274291
expect(console.error).toHaveBeenCalledTimes(2)
275292
console.error.mockClear()
276293

294+
// recover via try again button
277295
userEvent.click(screen.getByText(/try again/i))
278296
expect(screen.queryByRole('alert')).not.toBeInTheDocument()
297+
expect(console.error).not.toHaveBeenCalled()
298+
expect(handleReset).toHaveBeenCalledWith(TRY_AGAIN_ARG1, TRY_AGAIN_ARG2)
299+
expect(handleReset).toHaveBeenCalledTimes(1)
300+
handleReset.mockClear()
279301

302+
// blow it up again
280303
userEvent.click(screen.getByText('toggle explode'))
281304
screen.getByRole('alert')
282305
expect(console.error).toHaveBeenCalledTimes(2)
283306
console.error.mockClear()
284307

308+
// recover via resetKeys change
285309
userEvent.click(screen.getByText('toggle explode'))
310+
expect(handleReset).toHaveBeenCalledWith([true], [false])
311+
expect(handleReset).toHaveBeenCalledTimes(1)
312+
handleReset.mockClear()
286313
expect(screen.queryByRole('alert')).not.toBeInTheDocument()
287314
expect(console.error).not.toHaveBeenCalled()
288315
})

src/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ const changedArray = (a = [], b = []) =>
66
const initialState = {error: null, info: null}
77
class ErrorBoundary extends React.Component {
88
state = initialState
9-
resetErrorBoundary = () => {
10-
this.props.onReset?.()
9+
resetErrorBoundary = (...args) => {
10+
this.props.onReset?.(...args)
1111
this.setState(initialState)
1212
}
1313

@@ -20,7 +20,7 @@ class ErrorBoundary extends React.Component {
2020
const {error} = this.state
2121
const {resetKeys} = this.props
2222
if (error !== null && changedArray(prevProps.resetKeys, resetKeys)) {
23-
this.resetErrorBoundary()
23+
this.resetErrorBoundary(prevProps.resetKeys, resetKeys)
2424
}
2525
}
2626

0 commit comments

Comments
 (0)