[React-복습] 5. React.Component 생명주기


React.Component 생명주기에 대한 스케치 포스팅이다.


01. React.Component 생명주기


01-1. 개요

React를 사용할 때는 컴포넌트를 class 또는 함수로 정의할 수 있습니다.
class로 정의된 컴포넌트는 아래에 자세히 설명하고 있듯 보다 많은 기능을 제공합니다. React 컴포넌트 class를 정의하려면 React.Component를 상속받아야 합니다.

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}


01-2. 컴포넌트 생명주기

모든 컴포넌트는 여러 종류의 “생명주기 메서드”를 가지며, 이 메서드를 오버라이딩하여 특정 시점에 코드가 실행되도록 설정


1) 마운트

아래 메서드들은 컴포넌트의 인스턴스가 생성되어 DOM 상에 삽입될 때에 순서대로 호출됩니다.

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()


2) 업데이트

props 또는 state가 변경되면 갱신이 발생합니다. 아래 메서드들은 컴포넌트가 다시 렌더링될 때 순서대로 호출됩니다.

  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()


3) 마운트 해제

아래 메서드는 컴포넌트가 DOM 상에서 제거(직전)될 때에 호출됩니다.

  • componentWillUnmount()


4) 오류 처리

아래 메서드들은 자식 컴포넌트를 렌더링하거나, 자식 컴포넌트가 생명주기 메서드를 호출하거나,
또는 자식 컴포넌트가 생성자 메서드를 호출하는 과정에서 오류가 발생했을 때에 호출됩니다.

  • static getDerivedStateFromError()
  • componentDidCatch()


5) 기타 API

  • setState()
  • forceUpdate()


6) class 프로퍼티

  • defaultProps
  • displayName


7) 인스턴스 프로퍼티

  • props
  • state


01-3. 주 사용되는 생명주기 메서드

컴포넌트 생명주기

  • constructor : state 초기화 및 메서드 바인딩
  • componentDidMount : Dom 노드 초기화 및 데이터 fetch
  • componentWillUnmount : 타이머 제거 및 요청 취소 구독 해제
  • Functional Component : hook 으로 대부분 구현 가능


ClassComponent 로 생명주기 예제

import React, { Component } from "react";

export default class ClassComponent extends Component {
  //state 초기화 및 메서드 바인딩
  constructor(props) {
    super(props);
    console.log("[life-cycle] constructor");
    this.state = { date: new Date() };
    //this.handleClick = this.handleClick.bind(this);
  }

  //Dom 노드 초기화 및 데이터 fetch
  componentDidMount() {
    console.log("[life-cycle] componentDidMount");
    this.timerID = setInterval(() => this.tick(), 3000);
  }

  componentDidUpdate() {
    console.log("[life-cycle] componentDidUpdate");
  }

  //타이머 제거 및 요청 취소 및 구독 해제
  componentWillUnmount() {
    console.log("[life-cycle] componentWillUnmount");
    clearInterval(this.timerID);
  }

  tick() {
    console.log("[life-cycle] tick");
    this.setState({ date: new Date() });
  }

  //handleClick() {// Arrow function을 쓰면 상단에 set 안해도 됨
  handleClick = () => {
    alert(this.state.date);
  };

  render() {
    console.log("[life-cycle] render");
    return (
      <div>
        <h1>[life-cycle] ClassComponent</h1>
        <button onClick={this.handleClick}>시간 Alert</button>
      </div>
    );
  }
}
ClassComponent.jsx:39 [life-cycle] render
ClassComponent.jsx:14 [life-cycle] componentDidMount
ClassComponent.jsx:24 [life-cycle] componentWillUnmount
ClassComponent.jsx:14 [life-cycle] componentDidMount
ClassComponent.jsx:29 [life-cycle] tick
ClassComponent.jsx:39 [life-cycle] render
ClassComponent.jsx:39 [life-cycle] render
ClassComponent.jsx:19 [life-cycle] componentDidUpdate
ClassComponent.jsx:29 [life-cycle] tick
ClassComponent.jsx:39 [life-cycle] render
ClassComponent.jsx:39 [life-cycle] render
ClassComponent.jsx:19 [life-cycle] componentDidUpdate
ClassComponent.jsx:29 [life-cycle] tick
ClassComponent.jsx:39 [life-cycle] render
ClassComponent.jsx:39 [life-cycle] render
ClassComponent.jsx:19 [life-cycle] componentDidUpdate
ClassComponent.jsx:29 [life-cycle] tick
ClassComponent.jsx:39 [life-cycle] render
ClassComponent.jsx:39 [life-cycle] render
ClassComponent.jsx:19 [life-cycle] componentDidUpdate