React
클래스형 컴포넌트 생명주기
Mount
- 처음 화면에 나타날 때
- 컴포넌트가 DOM 에 처음 추가될 때 호출되는 메서드
constructor() + render()
-> componentDidMount()
componentDidMount()
- 마운트 완료 후 비동기 데이터 로딩, 타이머 등록 등에 자주 사용
Update
- props 또는 state 가 변경돼서 리렌더링이 일어날 때
- 이전 props/state 를 비교해서 필요한 로직을 실행하는 데 사용
render()
-> componentDidUpdate(prevProps, prevState)
Unmount
- 컴포넌트가 DOM 에서 제거되기 직전 호출
componentWillUnmount()
- 주로 타이머 해제, 리스터 제거 등 저리 용도로 사용
함수형 컴포넌트 생명주기
Mount
- 빈 배열 useEffect
- 컴포넌트가 처음 마운트될 때만 실행됩니다. (한 번만 호출)
1
2
3
useEffet(() => {
console.log("컴포넌트가 마운트됨");
}, []);
Update
- 특정 state, props 가 변경될 때만 실행되도록 의존성 배열 사용
1
2
3
useEffet(() => {
console.log("count 값이 바뀔 때마다 실행됨");
}, [count]);
- 만약 배열이 비어있지 않으면 mount + update 모두 실행됩니다.
Unmount
- 컴포넌트가 사라지기 직전에 실행되는 cleanup 함수 반환
1
2
3
4
5
6
7
8
9
10
useEffect(() => {
const timer = setInterval(() => {
console.log("타이머 동작 중");
}, 1000);
return () => {
console.log("컴포넌트 언마운트됨 → 타이머 제거");
clearInterval(timer);
};
}, []);
알림 예제
Notification
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
import React, { Component } from 'react';
const styles = {
wrapper: {
margin: 8,
padding: 8,
display: "flex",
flexDirection: "row",
border: "1px solid grey",
borderRadius: 16,
},
messageText: {
color: "black",
fontSize: 16,
},
};
class Notification extends Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() {
console.log(`${this.props.id} componentDidMount called`);
}
componentDidUpdate() {
console.log(`${this.props.id} componentDidUpdate called`);
}
componentWillUnmount() {
console.log(`${this.props.id} componentWillUnmount called`);
}
render() {
return (
<div style={styles.wrapper}>
<span style={styles.messageText}>{this.props.message}</span>
</div>
);
}
}
export default Notification;
NotificationList
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
import React, { Component } from 'react';
import Notification from './Notification';
const reservedNotifications = [
{
id:1,
message: "안녕하세요, 오늘 일정을 알려드립니다.",
},
{
id:2,
message: "점심식사 시간입니다.",
},
{
id:3,
message: "이제 곧 수업이 시작됩니다.",
}
];
var timer;
class NotificationList extends Component {
constructor(props) {
super(props);
this.state = {
notifications: [],
};
}
componentDidMount() {
const { notifications } = this.state;
timer = setInterval(() => {
if (notifications.length < reservedNotifications.length) {
const index = notifications.length;
notifications.push(reservedNotifications[index]);
this.setState({
notifications: notifications,
});
} else {
this.setState({
notifications: [],
});
clearInterval(timer);
}
}, 3000);
}
componentWillUnmount() {
clearInterval(timer);
}
render() {
return (
<div>
{this.state.notifications.map((notification) => {
return (
<Notification
key={notification.id}
id={notification.id}
message={notification.message}
/>
);
})}
</div>
);
}
}
export default NotificationList;
- setState() 는 컴포넌트 전체를 다시 렌더링
- this.setState() -> NotificationList 전체가 리렌더링
- render() 함수가 다시 실행되고 this.state.notification.map(…) 다시 호출
- Notification 3번이 mount 될 때, 1번과 2번 모두 update
- React 는 각 자식 컴포넌트에게 ‘업데이트 여부’ 를 판단시킵니다
componentDidUpdate()
- 자기 자신의 props 가 변경된 경우
- 부모가 리렌더링 되면서 자신도 리렌더링 되었고, shouldComponentUpdate() 가 true 인 경우
이 글은 저작권자의 CC BY 4.0 라이센스를 따릅니다.