Programming/React

[React] 컴포넌트 생명주기

Bam_t 2021. 11. 10. 16:13
728x90

리액트의 컴포넌트는 생성부터 소멸까지 생명 주기(라이프 사이클)를 가지고 있습니다. 개발자는 이 생명주기 함수들을 이용해서 생성부터 사이의 원하는 시점에 동작을 삽입할 수 있습니다.


1. 컴포넌트 라이프 사이클 메소드

서론에서 간단히 소개했듯이 리액트의 모든 컴포넌트들은 생명 주기를 가지고 동작합니다. 단순히 만들고 실행!에서 끝나는 것이 아니라 만드는 순간부터 실행 종료 사이사이 모든 순간들을 메소드로 나누어 관리합니다. 이것들을 컴포넌트 라이프 사이클 메소드라고 합니다. 컴포넌트 라이프 사이클 메소드는 클래스형 컴포넌트에서만 직접 사용이 가능하지만 함수형 컴포넌트에서 Hooks 기능을 이용해서 사용할 수 있습니다. 이 포스트의 현재 목적은 라이프 사이클 메소드의 이해이므로 Hooks를 이용한 방식은 다음에 따로 다루고, 클래스형 컴포넌트를 예시로 소개하겠습니다.

컴포넌트는 크게 세 가지 주기를 가집니다. 컴포넌트를 브라우저에 그리는 마운트(Mount), 컴포넌트를 브라우저에 그린 후 변경 사항을 그리는 업데이트(Update), 컴포넌트를 브라우저에서 제거하는 언마운트(Unmount)과정을 가지고있습니다.

그럼 이제 각 과정에서 사용되는 라이프 사이클 메소드들을 알아보겠습니다.

 

 

2. 마운트 과정의 라이프 사이클 메소드

처음으로 살펴볼 라이프 사이클 메소드들은 마운트 과정에서 사용할 수 있는 라이프 사이클 메소드들 입니다. 각 라이프 사이클 메소드들은 특징을 가지고 있는데요. 게터(get)와 세터(set)처럼 메소드 이름에 will이 붙으면 특정 작업 이전에 실행되는 메소드이고, did가 붙으면 특정 작업 이후에 실행된다는 특징을 가지고 있습니다.

마운트란 DOM이 생성되어 브라우저에 나타나는 과정을 말합니다. 즉, 컴포넌트를 만들고 브라우저에 표시되게 하는 것 까지의 과정을 마운트라고 할 수 있습니다.

 

consturctor

constructor(props) {}

생성자라는 이름 답게, 이 함수는 컴포넌트를 새로 생성할 때 마다 호출되는 메소드입니다. state를 다룰 때 예제에서 한 번 등장한 적이 있었는데요. 그 사용처 처럼 컴포넌트 생성시 가장 처음 호출되는 동시에, state나 객체 변수 등을 선언할 때 사용됩니다.

 

getDerivedStateFromProps

getDerivedStateFromProps(props, state) {}

props로 전달된 인자 값을 state에 넣을 때 이용하는 메소드입니다. 이 메소드는 정적 메소드라서 this 등을 이용한 접근은 허용되지 않고 인자로 전달된 값을 통해서 사용해야합니다. 이때 props는 상위 컴포넌트에서 인수로 전달한 값이고, state는 현재 컴포넌트의 state 값입니다. 즉 이 메소드는 보통 상위에서 정보를 받아 현재 state에 적용하는 식으로 이용하게 됩니다.

 

render

render() {}

render 메소드도 클래스형 컴포넌트를 다룰때 봤던 메소드입니다. 이 메소드 역시 라이프 사이클 메소드입니다. 변경 사항을 나타낼 때 호출 되는 함수입니다. render() {} 내부의 JSX를 화면에 그려줍니다.

 

componentDidMount

componentDidMount() {}

컴포넌트가 브라우저에 생성되어 표시된다면 호출되는 메소드입니다. js DOM 조작의 'DOMContentLoaded'처럼 모든 컴포넌트가 그려진 이후에 특정 동작을 실행하고 싶다면, 이 메소드를 이용하게 됩니다.

 

 

 

3. 업데이트 과정의 라이프 사이클 메소드

이번에는 업데이트 과정에서 사용가능한 라이프 사이클 메소드들입니다. 업데이트 과정을 거친 컴포넌트는 리렌더링을 통해서 브라우저에 나타나게 됩니다. 업데이트는 컴포넌트에 변경사항이 발생될 때 업데이트를 실시하는데, 이는 다음 네 가지 경우에 업데이트를 실시합니다.

  • props의 변경
  • state의 변경
  • 부모 컴포넌트의 리렌더링
  • this.forceUpdate()를 통한 강제 렌더링

 

getDerivedStateFromProps

getDerivedStateFromProps(props, state) {}

이 메소드는 조금 전 마운트 과정에서도 있었습니다. 마찬가지로 업데이트 내역을 현재 컴포넌트에 적용하기 위해 사용합니다.

 

shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState) {}

이 메소드는 컴포넌트를 리렌더링을 할지 말지 결정합니다. 그래서 반환값으며 true/false를 가집니다. true를 반환할 시에는 계속해서 생명주기를 진행하고 false를 반환할 경우 중지합니다. 데이터 비교가 포함된 메소드라 성능에 영향을 주는 메소드이기도 합니다. 또한 this.forceUpdate() 통해 강제로 리렌더링 하는 경우에 이 메소드는 실행되지 않습니다.

 

render

마찬가지로 업데이트 리렌더링을 위해 render 메소드를 포함하고 있습니다.

 

getSnapshotBeforeUpdate

getSnapshotBeforeUpdate(preProps, preState) {}

 

리렌더링 직전에 호출되는 메소드입니다. 이 메소드는 출력 직전에 호출되므로, 출력 직전의 렌더링 요소 크기나 스크롤 위치등의 DOM의 정보에 접근할 때 사용합니다.

 

componentDidUpdate

componentDidUpdate(preProps, preState, snapshot) {}

컴포넌트가 모든 업데이트를 마친 후에 호출 됩니다. 세번째 인자인 snapshot은 getSnapshotBeforeUpdate() 함수로 부터 반환된 DOM정보를 전달 받은 인자입니다. 이 3가지 인자들을 이용해서 스크롤 위치 변경 등의 DOM 정보 변경이 가능합니다.

 

 

4. 언마운트 과정의 라이프 사이클 메소드

언마운트는 DOM에서 컴포넌트를 제거하는 과정입니다. 당연하지만 삭제과정은 컴포넌트를 삭제하는 것이라 삭제하기 직전만이 컴포넌트를 제어할 수 있습니다.

 

componentWillUnmount

componentWillUnmount() {}

컴포넌트가 브라우저에서 삭제되기 직전에 호출되는 메소드입니다. 보통 컴포넌트 내에서 메모리를 잡고있는 컴포넌트 일 경우 메모리 해제를 위해 사용됩니다.

 

 

 

5. 라이프 사이클 메소드 사용

위에서 알아본 컴포넌트의 라이프 사이클을 정리하면 다음과 같이 나타낼 수 있습니다.

 

import React from 'react';

class ComponentLifeCycle extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            destroyed: false,
        };

        console.log("constructor() 메소드 호출");
    }

    static getDerivedStateFromProps() {
        console.log("getDerivedStateFromProps() 메소드 호출");

        return {};
    }

    componentDidMount() {
        console.log("componentDidMount() 메소드 호출");

        this.setState({updated: true});
    }

    shouldComponentUpdate() {
        console.log("shouldComponentUpdate() 메소드 호출");

        return true;
    }

    getSnapshotBeforeUpdate() {
        console.log("getSnapshotBeforeUpdate() 메소드 호출");

        return {};
    }

    componentDidUpdate() {
        console.log("componentDidUpdate() 메소드 호출");
    }

    componentWillUnmount() {
        console.log("componentWillUnmount() 메소드 호출")
    }

    render() {
        console.log("render() 메소드 호출");

        return null;
    }
}

export default ComponentLifeCycle;

위에서 본 순서대로 선언 순서에 상관없이 호출이 되었죠? 여기서는 따로 삭제 과정을 거치지 않았기 때문에 componentWillUnMount가 실행되지 않았지만, 삭제를 준다면 제일 마지막에 componentWillUnMount가 호출될 것 입니다.


참조

https://ko.reactjs.org/docs/state-and-lifecycle.html

 

State and Lifecycle – React

A JavaScript library for building user interfaces

ko.reactjs.org

https://ko.reactjs.org/docs/react-component.html

 

React.Component – React

A JavaScript library for building user interfaces

ko.reactjs.org

https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

 

React Lifecycle Methods diagram

Fully interactive and accessible React Lifecycle Methods diagram.

projects.wojtekmaj.pl

728x90