/
ReactDevOverlay.tsx
95 lines (86 loc) · 2.55 KB
/
ReactDevOverlay.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import * as React from 'react'
import {
ACTION_UNHANDLED_ERROR,
OverlayState,
UnhandledErrorAction,
} from './error-overlay-reducer'
import { ShadowPortal } from './components/ShadowPortal'
import { BuildError } from './container/BuildError'
import { Errors, SupportedErrorEvent } from './container/Errors'
import { Base } from './styles/Base'
import { ComponentStyles } from './styles/ComponentStyles'
import { CssReset } from './styles/CssReset'
import { parseStack } from './helpers/parseStack'
import { RootLayoutError } from './container/RootLayoutError'
interface ReactDevOverlayState {
reactError: SupportedErrorEvent | null
}
class ReactDevOverlay extends React.PureComponent<
{
state: OverlayState
children: React.ReactNode
onReactError: (error: Error) => void
},
ReactDevOverlayState
> {
state = { reactError: null }
static getDerivedStateFromError(error: Error): ReactDevOverlayState {
const e = error
const event: UnhandledErrorAction = {
type: ACTION_UNHANDLED_ERROR,
reason: error,
frames: parseStack(e.stack!),
}
const errorEvent: SupportedErrorEvent = {
id: 0,
event,
}
return { reactError: errorEvent }
}
componentDidCatch(componentErr: Error) {
this.props.onReactError(componentErr)
}
render() {
const { state, children } = this.props
const { reactError } = this.state
const hasBuildError = state.buildError != null
const hasRuntimeErrors = Boolean(state.errors.length)
const rootLayoutMissingTagsError = state.rootLayoutMissingTagsError
const isMounted =
hasBuildError ||
hasRuntimeErrors ||
reactError ||
rootLayoutMissingTagsError
return (
<>
{reactError ? (
<html>
<head></head>
<body></body>
</html>
) : (
children
)}
{isMounted ? (
<ShadowPortal>
<CssReset />
<Base />
<ComponentStyles />
{rootLayoutMissingTagsError ? (
<RootLayoutError
missingTags={rootLayoutMissingTagsError.missingTags}
/>
) : hasBuildError ? (
<BuildError message={state.buildError!} />
) : reactError ? (
<Errors initialDisplayState="fullscreen" errors={[reactError]} />
) : hasRuntimeErrors ? (
<Errors initialDisplayState="minimized" errors={state.errors} />
) : undefined}
</ShadowPortal>
) : undefined}
</>
)
}
}
export default ReactDevOverlay