1
- import * as React from 'react' ;
1
+ import React , { useState , useEffect , FC } from 'react' ;
2
+ import { useLocation } from 'react-router-dom' ;
2
3
import { ContentWrapper } from './Layout/ContentWrapper' ;
3
4
import { PageTemplate } from './Layout/PageTemplate' ;
4
- export default class ErrorBoundary extends React . Component <
5
- any ,
6
- { hasError : boolean ; error : Error | null }
7
- > {
5
+
6
+ interface Props {
7
+ hasError : boolean ;
8
+ error : Error | null ;
9
+ }
10
+
11
+ class ErrorBoundaryDetail extends React . Component < any , Props > {
8
12
constructor ( props : any ) {
9
13
super ( props ) ;
10
14
this . state = { hasError : false , error : null } ;
11
15
}
12
16
13
17
static getDerivedStateFromError ( error : Error ) {
14
- // Update state so the next render will show the fallback UI.
15
18
return { hasError : true , error } ;
16
19
}
17
20
21
+ componentDidUpdate ( prevProps : Props ) {
22
+ if ( ! this . props . hasError && prevProps . hasError ) {
23
+ this . setState ( { hasError : false } ) ;
24
+ }
25
+ }
26
+
18
27
componentDidCatch ( error : Error ) {
19
- // You can also log the error to an error reporting service
20
28
console . error ( error ) ;
29
+ this . props . setHasError ( true ) ;
21
30
}
22
31
23
32
render ( ) {
24
33
if ( this . state . hasError ) {
25
- // You can render any custom fallback UI
26
34
return (
27
- < PageTemplate documentTitle = "Error" path = { [ { label : 'Error' } ] } >
35
+ < PageTemplate
36
+ documentTitle = "Error"
37
+ path = { [
38
+ {
39
+ label : 'Error' ,
40
+ } ,
41
+ ] }
42
+ >
28
43
< ContentWrapper >
29
44
< h3 > Something went wrong.</ h3 >
30
45
< pre > { this . state . error ?. message } </ pre >
@@ -37,3 +52,25 @@ export default class ErrorBoundary extends React.Component<
37
52
return this . props . children ;
38
53
}
39
54
}
55
+
56
+ /** Function component wrapper as we need useEffect to set the state back to false on location changing **/
57
+ const ErrorBoundary : FC < {
58
+ children : React . ReactNode ;
59
+ } > = ( { children } ) => {
60
+ const [ hasError , setHasError ] = useState < boolean > ( false ) ;
61
+ const location = useLocation ( ) ;
62
+
63
+ useEffect ( ( ) => {
64
+ if ( hasError ) {
65
+ setHasError ( false ) ;
66
+ }
67
+ } , [ location . key ] ) ;
68
+
69
+ return (
70
+ < ErrorBoundaryDetail hasError = { hasError } setHasError = { setHasError } >
71
+ { children }
72
+ </ ErrorBoundaryDetail >
73
+ ) ;
74
+ } ;
75
+
76
+ export default ErrorBoundary ;
0 commit comments