@@ -5,6 +5,10 @@ const changedArray = (a = [], b = []) =>
5
5
6
6
const initialState = { error : null , info : null }
7
7
class ErrorBoundary extends React . Component {
8
+ static getDerivedStateFromError ( error ) {
9
+ return { error}
10
+ }
11
+
8
12
state = initialState
9
13
resetErrorBoundary = ( ...args ) => {
10
14
this . props . onReset ?. ( ...args )
@@ -13,13 +17,17 @@ class ErrorBoundary extends React.Component {
13
17
14
18
componentDidCatch ( error , info ) {
15
19
this . props . onError ?. ( error , info ?. componentStack )
16
- this . setState ( { error , info} )
20
+ this . setState ( { info} )
17
21
}
18
22
19
23
componentDidUpdate ( prevProps ) {
20
- const { error} = this . state
24
+ const { error, info } = this . state
21
25
const { resetKeys} = this . props
22
- if ( error !== null && changedArray ( prevProps . resetKeys , resetKeys ) ) {
26
+ if (
27
+ error !== null &&
28
+ info !== null &&
29
+ changedArray ( prevProps . resetKeys , resetKeys )
30
+ ) {
23
31
this . props . onResetKeysChange ?. ( prevProps . resetKeys , resetKeys )
24
32
this . setState ( initialState )
25
33
}
@@ -30,6 +38,15 @@ class ErrorBoundary extends React.Component {
30
38
const { fallbackRender, FallbackComponent, fallback} = this . props
31
39
32
40
if ( error !== null ) {
41
+ // we'll get a re-render with the error state in getDerivedStateFromError
42
+ // but we don't have the info yet, so just render null
43
+ // note that this won't be committed to the DOM thanks to our componentDidCatch
44
+ // so the user won't see a flash of nothing, so this works fine.
45
+ // the benefit of doing things this way rather than just putting both the
46
+ // error and info setState within componentDidCatch is we avoid re-rendering
47
+ // busted stuff: https://github.com/bvaughn/react-error-boundary/issues/66
48
+ if ( ! info ) return null
49
+
33
50
const props = {
34
51
componentStack : info ?. componentStack ,
35
52
error,
0 commit comments