[React #7] Component Lifecycle(생애주기) Methods

Component Lifecycle

  • React components는 create, render, DOM에 추가, 업데이트, 삭제될 수 있다. 이 모든 스텝들을 '컴포넌트의 생명주기(lifecycle)'라고 한다.
  • lifecyle은 Mounting - Updating - Unmounting의 3단계를 거친다.
    출처: codeacademy

1. Mounting - 컴포넌트 호출

  • 컴포넌트가 초기화되고 DOM에 놓이는 첫 순간으로 Mount 되지 않으면 화면에서 볼 수 없다.
  • constructor(), render(), componentDidMount() 메서드가 실행된다.

2. Updating - 상태 업데이트

  • state나 props의 상태 변화에 따라 컴포넌트가 업데이트 될 때
  • 정적인 컴포넌트(예: 로고)를 제외하고 컴포넌트의 상태값이 변하거나, 다른 props가 컴포넌트에 전달될 때 업데이트 된다.
    -render(), componentDidUpdate() 메서드가 실행된다.

3. Unmounting - 제거

  • 컴포넌트가 DOM에서 삭제될 때
  • componentWillUnmount() 메서드가 실행된다.

Lifecycle Methods

컴포넌트의 생애주기 각각의 부분을 의미한다. 각각의 메서드는 React.component class에서 제공하는 메서드로 class 메서드를 생성할 때 사용할 수 있고, lifecycle에 따라 각자의 메서드가 호출된다.

import React from 'react';

export class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = { date: new Date() };
  }
  render() {
    return (
      <div>
        {this.props.isPrecise
          ? this.state.date.toISOString()
          : this.state.date.toLocaleTimeString()}
      </div>
    );
  }
  startInterval() {
    let delay;
    if (this.props.isPrecise) {
      delay = 100;
    } else {
      delay = 1000;
    }
    this.intervalID = setInterval(() => {
      this.setState({ date: new Date() });
    }, delay);
  }
  componentDidMount() {
    this.startInterval();
  }
  componentDidUpdate(prevProps) {
    if (this.props.isPrecise === prevProps.isPrecise) {
      return;
    }
    clearInterval(this.intervalID);
    this.startInterval();
  }
  componentWillUnmount() {
    clearInterval(this.intervalID);
  }
}

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

Mounting 단계 메서드

constructor() mounting 단계에서 일어나는 첫번째 메소드
render() mounting 단계 후반에 일어나는 메서드. 컴포넌트를 최초로 렌더링할때 필요하며 updating 단계에서 컴포넌트를 재실행(re-render)한다.
componentDidMount()

  • mounting 단계의 제일 마지막 메서드로 1) Constructor 2) render() 3)componentDidMount 순으로 실행된다.
    즉, componentDidMount는 컴포넌트가 초기 렌더링된 후 실행된다!
  • 위의 예시에서 setInterval() 함수는 본인 컴포넌트 내에서 값이 업데이트 되는 경우이므로 componentDidMount에 쓴다.
    ❓ render()에 쓰면 안되나?
    => render()는 mounting 단계, updating 단계에서 두 번 실행되는 함수로 너무 자주 실행되 버그가 일어날 수 있다.
    ❓ 그럼 constructor()에 쓰면 안되나?
    -> mounting 단계에서 일어나는데 *단일 책임 원칙(Single Responsibility Principle(SRP))에 어긋나고, 버그를 일으킬 수 있다.
    **단일 책임 원칙: 객체 지향 프로그래밍에서 단일 책임 원칙(single responsibility principle)이란 모든 클래스는 하나의 책임만 가지며, 클래스는 그 책임을 완전히 캡슐화해야 함을 일컫는다.

Updating 단계 메서드

props나 state를 변경하거나 컴포넌트에 props를 전달하는 경우 update를 유발한다.
컴포넌트를 업데이트할 때 쓰는 메서드는 다양한데(updating 메서드 종류), 주로 componentDidUpdate()render()를 쓴다.
componentDidUpdate(prevProps, prevState, snapshot)

  • 업데이트가 일어난 직후 실행되는 메서드로 조건에 맞게 써주어야 한다.
componentDidUpdate(prevProps) {
  // Typical usage (don't forget to compare props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}

render() 컴포넌트가 업데이트 될 때 render()가 다시 호출되면서 변경된 부분을 보여준다.

Unmounting 단계 메서드

compoentWillUnmount()

  • 컴포넌트를 종료할 때 Unmounting 단계에서 쓴다.
  • 컴포넌트를 제대로 종료하지 않으면 버그를 일으키거나 AJAX의 데이터를 많이 쓰고, DOM의 활동이 느려지는 등 많은 부작용이 발생할 수 있다.
  • setInterVal()과 같이 별다른 조치가 없으면 계속 작동하는 함수는 clearInterval()로 제대로 끝내준다.
    (컴퓨터에 USB를 걍 뽑아버리는 것과 '종료하기' 처리 해주는 것의 차이가 아닐까..?)

좋은 웹페이지 즐겨찾기