Appearance
ErrorBoundary
what is Error Boundaries ?
部分UI的错误,不应该导致整个应用的崩溃,也就是说某一个组件发生错误,不应该影响其他组件的正常渲染,错误边界就是为了解决这个问题而引入的(在React 16中引入)
How to use Error Boundaries ?
在class组件中,若使用了 componentDidCatch
或 static getDerivedStateFromError
这两个方法中的任意一个(或两个),该组件就是错误边界组件
需要注意的是,错误边界只针对组件,且只有 class 组件才可以称为错误边界组件
examples
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// 更新 state 使下一次渲染能够显示降级后的 UI
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// 你同样可以将错误日志上报给服务器
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
// 你可以自定义降级后的 UI 并渲染
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import React, { Component } from 'react'
class ErrorBundary extends Component {
constructor(props) {
super(props);
this.state = {
error: null,
errorInfo: null
}
}
componentDidCatch(error, errorInfo) {
this.setState({
error: error,
errorInfo: errorInfo
})
}
render() {
if (this.state.errorInfo) {
return (
<>
<h2>Something went wrong.</h2>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.toString()}
<br />
{this.state.errorInfo.componentStack}
</details>
</>
)
}
return this.props.children;
}
}
class BuggyCounter extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 0
}
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(({ counter }) => ({
counter: counter + 1
}))
}
render() {
if (this.state.counter === 5) {
throw new Error("I crashed");
}
return <h1 onClick={this.handleClick}>{this.state.counter}</h1>
}
}
function App() {
return (
<>
<div>
<h2>两个组件在一个相同的错误边界中,若其中一个发生错误,则错误边界会替代该部分内容</h2>
<ErrorBundary>
<BuggyCounter />
<BuggyCounter />
</ErrorBundary>
</div>
<hr />
<div>
<h2>两个相同的组件,每个都包裹一个错误边界,其中一个错误也不会影响另一个组件</h2>
<ErrorBundary>
<BuggyCounter />
</ErrorBundary>
<ErrorBundary>
<BuggyCounter />
</ErrorBundary>
</div>
</>
)
}
export default App;
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
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