React.js Component LifeCycle API

React.js Component LifeCycle API

이번에는 React.js 컴포넌트의 LifeCycle API 에 관하여 살펴보겠다.
LifeCycle API는, 컴포넌트가 DOM 위에 생성되기 전 후 및 데이터가 변경되어 상태를 업데이트하기 전 후로 실행되는 메소드들 이다.
이 메소드를 왜 쓰는것인가? 과연 쓸일이 있을까? 라고 생각할 수 있는데, 가끔 이를 사용하지 않으면 해결 할 수 없는 난관에 가끔 부딪치기도 때문에 잘 알아뒀다가 필요 할 때 사용하는것이 좋다.
저번 편에서도 전화번호부를 구현 할 때, 인풋박스에 기본값을 전달 해 줄때와, 자원낭비를 줄이기 위하여 코드를 최적화 할 떄 LifeCycle API 가 사용되었다.

1. 시작하기

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
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
number: 0,
show: false
}
}

_increase() {
this.setState({
number: this.state.number + 1
});
}

_show() {
this.setState({
show: true
});
}

_unmount() {
this.setState({
number: 0,
show: false
});
}

render(){
let component = (<Card number={this.state.number} />);

return (
<div>
<Button caption="Show Card" customClass="green" onClick={this._show.bind(this)} />
<Button caption="Increase Number" customClass="blue" onClick={this._increase.bind(this)} />
<Button caption="Unmount Card" customClass="red" onClick={this._unmount.bind(this)} />
{this.state.show ? component : ''}
</div>
);
}
}

class Button extends React.Component {
render() {
let className = "ui button " + this.props.customClass;

return (
<div onClick={this.props.onClick}className={className}>{this.props.caption}</div>

)
}
}

class Card extends React.Component {
constructor(props) {
super(props);
console.log('constructor');
}

componentWillMount() {
console.log('componentWillMount');
}

componentDidMount() {
console.log('componentDidMount');
}

componentWillReceiveProps(nextProps) {
console.log('componentWillReceiveProps: ' + JSON.stringify(nextProps));
}

shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate: ' + JSON.stringify(nextProps) + ' ' + JSON.stringify(nextState));

return true;
}

componentWillUpdate(nextProps, nextState) {
console.log('componentWillUpdate: ' + JSON.stringify(nextProps) + ' ' + JSON.stringify(nextState));
}

componentDidUpdate(prevProps, prevState) {
console.log('componentDidUpdate: ' + JSON.stringify(prevProps) + ' ' + JSON.stringify(prevState));
}

componentWillUnmount() {
console.log('componentWillUnmount');
}

render() {
console.log('render');

return (
<div className="ui card">
<div className="content">
number: {this.props.number}
</div>
</div>
)
}
}

ReactDOM.render(<App/>, document.getElementById('app'));

컴포넌트를 생성 할 때는 constructor -> componentWillMount -> render -> componentDidMount 순으로 진행된다.
컴포넌트를 제거 할 때는 componentWillUnmount 메소드만 실행된다.
컴포넌트의 prop이 변경될 때엔 componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate-> render -> componentDidUpdate 순으로 진행됩니다.
이 예제에는 없지만 state가 변경될 떄엔 props 를 받았을 때 와 비슷하지만 shouldComponentUpdate 부터 시작된다.

2. 정리

LifeCycle API를 정리하면 다음과 같다.

React.js LifeCycle API 플로우 차트

3. 자세히 알아보기

위 메소드들이 어떤 역할을 하는지 자세히 알아보자.

constructor

1
2
3
4
constructor(props) {
super(props);
console.log('constructor');
}

생성자 메소드로서 컴포넌트가 처음 만들어 질 때 실행된다.
이 메소드에서 기본 state 를 정할 수 있다.

componentWillMount

1
2
3
componentWillMount() {
console.log('componentWillMount');
}

컴포넌트가 DOM 위에 만들어지기 전에 실행된다.

render

컴포넌트 렌더링을 담당한다.

componentDidMount

1
2
3
componentDidMount() {
console.log('componentDidMount');
}

컴포넌트가 만들어지고 첫 렌더링을 다 마친 후 실행되는 메소드이다.
이 안에서 다른 JavaScript 프레임워크를 연동하거나, setTimeout, setInterval 및 AJAX 처리 등을 넣는다.

componentWillReceiveProps

1
2
3
componentWillReceiveProps(nextProps) {
console.log('componentWillReceiveProps: ' + JSON.stringify(nextProps));
}

컴포넌트가 prop 을 새로 받았을 때 실행된다.
prop 에 따라 state 를 업데이트 해야 할 때 사용하면 유용하다.
이 안에서 this.setState() 를 해도 추가적으로 렌더링하지 않는다.

shouldComponentUpdate

1
2
3
4
5
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate: ' + JSON.stringify(nextProps) + ' ' + JSON.stringify(nextState));

return true;
}

prop 혹은 state 가 변경 되었을 때, 리렌더링을 할지 말지 정하는 메소드이다.
위 예제에선 무조건 true 를 반환 하도록 하였지만, 실제로 사용 할 떄는 필요한 비교를 하고 값을 반환하도록 하시길 바란다.
예: return nextProps.id !== this.props.id;
JSON.stringify() 를 쓰면 여러 field 를 편하게 비교 할 수 있다.

componentWillUpdate

1
2
3
componentWillUpdate(nextProps, nextState) {
console.log('componentWillUpdate: ' + JSON.stringify(nextProps) + ' ' + JSON.stringify(nextState));
}

컴포넌트가 업데이트 되기 전에 실행된다.
이 메소드 안에서는 this.setState() 를 사용하게 되면 무한루프에 빠져들게 되니 사용하지 않도록 하자.

componentDidUpdate

1
2
3
componentDidUpdate(prevProps, prevState) {
console.log('componentDidUpdate: ' + JSON.stringify(prevProps) + ' ' + JSON.stringify(prevState));
}

컴포넌트가 리렌더링을 마친 후 실행된다.

componentWillUnmount

1
2
3
componentWillUnmount(){
console.log("componentWillUnmount");
}

컴포넌트가 DOM 에서 사라진 후 실행되는 메소드이다.

참조

공유하기