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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
//App.js
import logo from './logo.svg';
import './App.css';
import React, {Component} from 'react';
import LifeCycle from "./life_cycle";
import ErrorBoundary from "./error_boundary";
//랜덤 색생 생성
function getRandomColor() {
return `#${Math.floor(Math.random() * 16777215).toString(16)}`;
}
class App extends Component {
state = {
color: '#000000'
}
handleClick = () => {
this.setState({
color: getRandomColor()
});
}
render() {
return (
<div>
<button onClick={this.handleClick}>Random color</button>
<ErrorBoundary>
<LifeCycle color={this.state.color}/>
</ErrorBoundary>
</div>
)
}
}
export default App;
//LifeCycle.js
import React, {Component} from 'react';
class LifeCycle extends Component {
state = {
number: 0,
color: null,
}
myRef = null;//ref 설정
constructor(props) {
super(props);
console.log('constructor');
}
static getDerivedStateFromProps(nextProps, prevState){
console.log('getDerivedStateFromProps');
if(nextProps.color !== prevState.color){
return {color: nextProps.color};
}
return null;
}
componentDidMount(){
console.log('componentDidMount');
}
shouldComponentUpdate(nextProps, nextState){
console.log('shouldComponentUpdate', nextProps, nextState);
return nextState.number % 10 !== 4;
}
componentWillUnmount() {
console.log('componentWillUnmount');
}
handleClick = () => {
this.setState({
number: this.state.number + 1
});
}
getSnapshotBeforeUpdate(prevProps, prevState){
console.log('getSnapshotBeforeUpdate');
if(prevProps.color !== this.props.color){
return this.myRef.style.color;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot){
console.log('componentDidUpdate', prevProps, prevState);
if(snapshot){
console.log('Previous color: ', snapshot);
}
}
render() {
console.log('render');
const style = {
color: this.props.color,
}
return (
<div>
{this.props.missing.value}
<h1 style={style} ref={ref => this.myRef=ref}>
{this.state.number}
</h1>
<p>color: {this.state.color}</p>
<button onClick={this.handleClick}>
add
</button>
</div>
)
}
}
export default LifeCycle;
|
cs |
결과:
에러 처리
위 코드에서 존재하지 않는 props를 하나 추가해 에러를 내보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import React, {Component} from 'react';
class LifeCycle extends Component {
//.......
render() {
//....
return (
<div>
{this.props.missing.value}
//......
</div>
)
}
}
export default LifeCycle;
|
cs |
이러면 TypeError: Cannot read property 'value' of undefined라는 에러창이 뜬다. 이는 개발 서버이기 때문이고 배포를 한다면 휜페이지만 보일것이다. 따라서 에러를 잡아주는 컴포넌트가 필요하다.
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
|
//ErrorBoundary.js
import React, {Component} from 'react';
class ErrorBoundary extends Component {
state = {
error: false
};
componentDidCatch(error, errorInfo) {
this.setState({
error: true
});
console.log({error, info});
}
render() {
if(this.state.eror) return <div>Error occurred</div>
return this.props.children;
}
}
export default ErrorBoundary;
//App.js
//...
import ErrorBoundary from "./error_boundary";
class App extends Component {
//...
render() {
return (
<div>
<button onClick={this.handleClick}>Random color</button>
<ErrorBoundary>
<LifeCycle color={this.state.color}/>
</ErrorBoundary>
</div>
)
}
}
|
cs |
위와 같이 에러 처리를 해주면 휜 화면 대신 다음과 같은 결과가 나온다