게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌6 - React - 8년 전 등록 / 4년 전 수정

React의 생명 주기(Life Cycle)

라이프사이클

안녕하세요. 이번 시간에는 React의 생명 주기에 대해서 알아보겠습니다. 갑자기 웬 생명 주기냐고요? React 컴포넌트생명 주기가 있습니다. 생애 주기 또는 라이프사이클(Life cycle)이라고도 많이 표현합니다. 컴포넌트가 실행되거나 업데이트되거나 제거될 때, 특정한 이벤트들이 발생합니다.

class 컴포넌트 대신 함수 컴포넌트에서의 라이프사이클이 궁금하시면 이 링크 를 눌러주세요.

지난 시간에 사용했던 코드에 추가로 코드를 더 넣었습니다.

import React, { Component } from 'react';
import PropTypes from 'prop-types';

export default class Basic extends Component {
  static propTypes = {
    name: PropTypes.string.isRequired,
    birth: PropTypes.number.isRequired,
    lang: PropTypes.string,
  };

  static defaultProps = {
    lang: 'Javascript',
  };

  static contextTypes = {
    router: PropTypes.object.isRequired,
  };

  state = {
    hidden: false,
  };

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

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

  componentWillReceiveProps(nextProps) {
    console.log('componentWillReceiveProps');
  }

  shouldComponentUpdate(nextProps, nextState) {
    console.log('shouldComponentUpdate');
    return true / false;
  }

  componentWillUpdate(nextProps, nextState) {
    console.log('componentWillUpdate');
  }

  componentDidUpdate(prevProps, prevState) {
    console.log('componentDidUpdate');
  }

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

  onClickButton = () => {
    this.setState({ hidden: true });
    this.refs.hide.disabled = true;
  }

  render() {
    return (
      <div>
        <span>저는 {this.props.lang} 전문 {this.props.name}입니다!</span>
        {!this.state.hidden && <span>{this.props.birth}년에 태어났습니다.</span>}
        <button onClick={this.onClickButton} ref="hide">숨기기</button>
        <button onClick={this.context.router.goBack}>뒤로</button>
      </div>
    );
  }
}

가운데에 component로 시작하는 것들이 많이 추가되었습니다. 위의 것들을 전부 다 사용할 필요는 없고 설명을 들은 뒤 필요한 것만 사용하시면 됩니다. 리액트 17부터는 componentWillMount, componentWillUpdate, componentWillReceiveProps 라이프 사이클이 deprecated됩니다!

undefined

Mount

컴포넌트가 처음 실행될 때 그것을 Mount라고 표현합니다. 컴포넌트가 시작되면 우선 context, defaultProps와 state를 저장합니다. 그 후에 componentWillMount 메소드를 호출합니다. 그리고 render로 컴포넌트를 DOM에 부착한 후 Mount가 완료된 후 componentDidMount가 호출됩니다.

주의할 점은, componentWillMount에서는 props나 state를 바꾸면 안 됩니다. Mount 중이기 때문이죠. 그리고 아직 DOM에 render하지 않았기 때문에 DOM에도 접근할 수 없습니다.

componentDidMount에서는 DOM에 접근할 수 있습니다. 그래서 여기에서는 주로 AJAX 요청을 하거나, setTimeout, setInterval같은 행동을 합니다.

정리하면 다음 순서로 실행됩니다.

  1. state, context, defaultProps 저장
  2. componentWillMount
  3. render
  4. componentDidMount

Props Update

props가 업데이트될 때의 과정입니다. 업데이트되기 전에 업데이트가 발생하였음을 감지하고, componentWillReceiveProps 메소드가 호출됩니다. 그 후 shouldComponentUpdate, componentWillUpdate가 차례대로 호출된 후, 업데이트가 완료(render)되면 componentDidUpdate가 됩니다. 이 메소드들은 첫 번째 인자로 바뀔 props에 대한 정보를 가지고 있습니다. componentDidUpdate만 이미 업데이트되었기 때문에 바뀌기 이전의 props에 대한 정보를 가지고 있습니다.

shouldcomponentUpdate에서는 아직 render하기 전이기 때문에 return false를 하면 render을 취소할 수 있습니다. 주로 여기서 성능 최적화를 합니다. 쓸데없는 update가 일어나면 여기서 걸러내는 거죠.

주의사항이 있는데, componentWillUpdate에서는 state를 바꿔서는 안 됩니다. 아직 props도 업데이트하지 않았으므로 state를 바꾸면 또 shouldComponentUpdate가 발생합니다. componentDidUpdate에서는 render이 완료되었기 때문에 DOM에 접근할 수 있습니다.

  1. componentWillReceiveProps
  2. shouldComponentUpdate
  3. componentWillUpdate
  4. render
  5. componentDidUpdate

State Update

setState 호출을 통해 state가 업데이트될 때의 과정입니다. props update와 과정이 같지만, componentWillReceiveProps 메소드는 호출되지 않습니다. 그리고 메소드의 두 번째 인자로는 바뀔 state에 대한 정보를 가지고 있습니다. componentDidUpdate는 두 번째 인자로 바뀌기 이전의 state에 대한 정보를 가지고 있습니다.

  1. shouldComponentUpdate
  2. componentWillUpdate
  3. render
  4. componentDidUpdate

Unmount

컴포넌트가 제거되는 것은 Unmount라고 표현합니다. 더는 컴포넌트를 사용하지 않을 때 발생하는 이벤트가 있습니다. componentWillUnmount가 그것입니다. componentDidUnmount는 없습니다. 이미 제거된 컴포넌트에서 이벤트를 발생시킬 수는 없겠죠? componentWillMount에서 주로 연결했던 이벤트 리스너를 제거하는 등의 여러 가지 정리 활동을 합니다.

  1. componentWillUnmount

다행히도 용도에 맞지 않는 메소드를 사용하면 React에서 자체적으로 에러 메시지를 띄워 줍니다. componentDidMount나 render에 setState를 사용한 경우도 에러 메시지를 띄웁니다. 그래도 혹시나 모를 상황에 대비하여 용도를 항상 알고 있는 게 좋겠습니다. 다음 시간에는 React-router에 대해 알아봅시다.

Error

에러 발생 시를 위한 componentDidCatch도 있습니다. 리액트 16에서 추가되었습니다.

componentDidCatch(error, info) {
  console.error(error, info);
}

위와 같이 사용하고, 최상위 컴포넌트에 한 번만 넣어주면 됩니다. 에러 발생 시 어떻게 대처할 것인지를 정의할 수 있습니다. 최소한 에러를 로깅하는 것만으로도 사용 가치가 있습니다.

getDerivedStateFromProps

리액트 16에서 추가된 라이프사이클입니다. props가 바뀌면 그에 따라 state도 같이 바꿔줍니다. 예를 들어 props.a가 10이고 derivedA state를 props.a의 10배로 설정해두었다면 derivedState는 기본적으로 100이 되겠죠? props.a가 11이 되었을 때 derivedA는 110으로 따라서 변경됩니다. 다만 개인적으로 실무에서는 써본 기억이 없습니다.

리액트 17부터는 componentWillMount, componentWillUpdate, componentWillReceiveProps 라이프 사이클이 deprecated됩니다!

다음 시간에는 주소에 따라 화면을 바꿔주는 리액트 라우터에 대해 알아봅시다!

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

4개의 댓글이 있습니다.
5년 전
감사합니다!! 보다가 궁금사항이 있어서 질문 드려요! getDerivedStateFromProps는 실무에서 어떤 상황에서 사용하는지 구체적인 예를 들어서 알려주시면 제가 이해를 좀더 잘할 수 있을 것 같습니다 ㅠㅠ
죄송하지만 구체적으로 어떨때 사용하는지 설명한번만 해주시면 감사드려욧!
5년 전
부모로부터 받은 props를 자식이 state로 쓸 때(원래 부모 props는 변경하지 못하는데 변경하고 싶을 때) 쓰긴 하는데 저는 실무하면서 한 번도 안 써봤습니다.
7년 전
정리 잘 해주셔서 감사합니다
7년 전
componentWillRecieveProps 에서 Receive 인데 오타가 있어요
7년 전
감사합니다~
7년 전
componentDidMount 에서는 setState 해도 괜찮습니다. ㅎㅎ 다만 setInterval식으로 state를 계속 변경시키는 로직이 아니면 가능한것 같아요~
7년 전
아 원래도 동작은 했습니다. 그리고 setInterval로 state를 바꿔도 됩니다. 공식 문서의 예제가 그렇게 되어있네요. 예전 공식문서에서는 componentDidMount에서 setState를 쓰지 말라고 했는데 그 부분이 사라진 것 같네요.