포스트

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 라이센스를 따릅니다.