@@ -38,14 +38,7 @@ then be gracefully handled.
38
38
- [ Error Recovery] ( #error-recovery )
39
39
- [ API] ( #api )
40
40
- [ ` ErrorBoundary ` props] ( #errorboundary-props )
41
- - [ ` children ` ] ( #children )
42
- - [ ` FallbackComponent ` ] ( #fallbackcomponent )
43
- - [ ` fallbackRender ` ] ( #fallbackrender )
44
- - [ ` fallback ` ] ( #fallback )
45
- - [ ` onError ` ] ( #onerror )
46
- - [ ` onReset ` ] ( #onreset )
47
- - [ ` resetKeys ` ] ( #resetkeys )
48
- - [ ` onResetKeysChange ` ] ( #onresetkeyschange )
41
+ - [ ` useErrorHandler(error?: Error) ` ] ( #useerrorhandlererror-error )
49
42
- [ Issues] ( #issues )
50
43
- [ 🐛 Bugs] ( #-bugs )
51
44
- [ 💡 Feature Requests] ( #-feature-requests )
@@ -190,13 +183,13 @@ specific scenario.
190
183
191
184
### ` ErrorBoundary ` props
192
185
193
- ### ` children `
186
+ #### ` children `
194
187
195
188
This is what you want rendered when everything's working fine. If there's an
196
189
error that React can handle within the children of the ` ErrorBoundary ` , the
197
190
` ErrorBoundary ` will catch that and allow you to handle it gracefully.
198
191
199
- ### ` FallbackComponent `
192
+ #### ` FallbackComponent `
200
193
201
194
This is a component you want rendered in the event of an error. As props it will
202
195
be passed the ` error ` , ` componentStack ` , and ` resetErrorBoundary ` (which will
@@ -205,7 +198,7 @@ when used in combination with the `onReset` prop).
205
198
206
199
This is required if no ` fallback ` or ` fallbackRender ` prop is provided.
207
200
208
- ### ` fallbackRender `
201
+ #### ` fallbackRender `
209
202
210
203
This is a render-prop based API that allows you to inline your error fallback UI
211
204
into the component that's using the ` ErrorBoundary ` . This is useful if you need
@@ -247,7 +240,7 @@ problem.
247
240
248
241
This is required if no ` FallbackComponent ` or ` fallback ` prop is provided.
249
242
250
- ### ` fallback `
243
+ #### ` fallback `
251
244
252
245
In the spirit of consistency with the ` React.Suspense ` component, we also
253
246
support a simple ` fallback ` prop which you can use for a generic fallback. This
@@ -262,12 +255,12 @@ const ui = (
262
255
)
263
256
```
264
257
265
- ### ` onError `
258
+ #### ` onError `
266
259
267
260
This will be called when there's been an error that the ` ErrorBoundary ` has
268
261
handled. It will be called with two arguments: ` error ` , ` componentStack ` .
269
262
270
- ### ` onReset `
263
+ #### ` onReset `
271
264
272
265
This will be called immediately before the ` ErrorBoundary ` resets it's internal
273
266
state (which will result in rendering the ` children ` again). You should use this
@@ -279,7 +272,7 @@ error happening again.
279
272
** Important** : ` onReset ` will _ not_ be called when reset happens from a change
280
273
in ` resetKeys ` . Use ` onResetKeysChange ` for that.
281
274
282
- ### ` resetKeys `
275
+ #### ` resetKeys `
283
276
284
277
Sometimes an error happens as a result of local state to the component that's
285
278
rendering the error. If this is the case, then you can pass ` resetKeys ` which is
@@ -289,11 +282,123 @@ then it will reset automatically (triggering a re-render of the `children`).
289
282
290
283
See the recovery examples above.
291
284
292
- ### ` onResetKeysChange `
285
+ #### ` onResetKeysChange `
293
286
294
287
This is called when the ` resetKeys ` are changed (triggering a reset of the
295
288
` ErrorBoundary ` ). It's called with the ` prevResetKeys ` and the ` resetKeys ` .
296
289
290
+ ### ` useErrorHandler(error?: Error) `
291
+
292
+ React's error boundaries feature is limited in that the boundaries can only
293
+ handle errors thrown during React's lifecycles. To quote
294
+ [ the React docs on Error Boundaries] ( https://reactjs.org/docs/error-boundaries.html ) :
295
+
296
+ > Error boundaries do not catch errors for:
297
+ >
298
+ > - Event handlers
299
+ > ([ learn more] ( https://reactjs.org/docs/error-boundaries.html#how-about-event-handlers ) )
300
+ > - Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks)
301
+ > - Server side rendering
302
+ > - Errors thrown in the error boundary itself (rather than its children)
303
+
304
+ This means you have to handle those errors yourself, but you probably would like
305
+ to reuse the error boundaries you worked hard on creating for those kinds of
306
+ errors as well. This is what ` useErrorHandler ` is for.
307
+
308
+ There are two ways to use ` useErrorHandler ` :
309
+
310
+ 1 . ` const handleError = useErrorHandler() ` : call ` handleError(theError) `
311
+ 2 . ` useErrorHandler(error) ` : useful if you are managing the error state yourself
312
+ or get it from another hook.
313
+
314
+ Here's an example:
315
+
316
+ ``` javascript
317
+ function Greeting () {
318
+ const [greeting , setGreeting ] = React .useState (null )
319
+ const handleError = useHandleError ()
320
+
321
+ function handleSubmit (event ) {
322
+ event .preventDefault ()
323
+ const name = event .target .elements .name .value
324
+ fetchGreeting (name).then (
325
+ newGreeting => setGreeting (newGreeting),
326
+ handleError,
327
+ )
328
+ }
329
+
330
+ return greeting ? (
331
+ < div> {greeting}< / div>
332
+ ) : (
333
+ < form onSubmit= {handleSubmit}>
334
+ < label> Name< / label>
335
+ < input id= " name" / >
336
+ < button type= " submit" onClick= {handleClick}>
337
+ get a greeting
338
+ < / button>
339
+ < / form>
340
+ )
341
+ }
342
+ ```
343
+
344
+ > Note, in case it's not clear what's happening here, you could also write
345
+ > ` handleClick ` like this:
346
+
347
+ ``` javascript
348
+ function handleSubmit (event ) {
349
+ event .preventDefault ()
350
+ const name = event .target .elements .name .value
351
+ fetchGreeting (name).then (
352
+ newGreeting => setGreeting (newGreeting),
353
+ error => handleError (error),
354
+ )
355
+ }
356
+ ```
357
+
358
+ Alternatively, let's say you're using a hook that gives you the error:
359
+
360
+ ``` javascript
361
+ function Greeting () {
362
+ const [name , setName ] = React .useState (' ' )
363
+ const {greeting , error } = useGreeting (name)
364
+ useHandleError (error)
365
+
366
+ function handleSubmit (event ) {
367
+ event .preventDefault ()
368
+ const name = event .target .elements .name .value
369
+ setName (name)
370
+ }
371
+
372
+ return greeting ? (
373
+ < div> {greeting}< / div>
374
+ ) : (
375
+ < form onSubmit= {handleSubmit}>
376
+ < label> Name< / label>
377
+ < input id= " name" / >
378
+ < button type= " submit" onClick= {handleClick}>
379
+ get a greeting
380
+ < / button>
381
+ < / form>
382
+ )
383
+ }
384
+ ```
385
+
386
+ In this case, if the ` error ` is ever set to a truthy value, then it will be
387
+ propagated to the nearest error boundary.
388
+
389
+ In either case, you could handle those errors like this:
390
+
391
+ ``` javascript
392
+ const ui = (
393
+ < ErrorBoundary FallbackComponent= {ErrorFallback}>
394
+ < Greeting / >
395
+ < / ErrorBoundary>
396
+ )
397
+ ```
398
+
399
+ And now that'll handle your runtime errors as well as the async errors in the
400
+ ` fetchGreeting ` or ` useGreeting ` code.
401
+
297
402
## Issues
298
403
299
404
_ Looking to contribute? Look for the [ Good First Issue] [ good-first-issue ]
0 commit comments