[ React.06.LifeCycle 함수 - Class형 Component ]

carrotsman·2023년 2월 13일
0

프론트엔드

목록 보기
24/34
post-thumbnail

React LifeCycle

React는 각 컴포넌트마다 고유의 생명주기(LifeCycle)을 가진다. class형 컴포넌트의 render 함수 전후로 각 생명주기 함수를 갖는다.

import React, { Component } from "react";

class Banner extends Component {
  render() {
    return <div>hello carrots</div>;
  }
}

export default Banner;

Banner라는 컴포넌트가 있다 가정해보자. DOM에 그려지고 없어지기 까지 과정(Life Cycle)이 있고 React에선 각 생명주기에 대한 컨트롤을 위해 메소드를 제공한다. 각 메소드는 Class형 컴포넌트에서만 사용가능하며 다음과 같은 프로세스를 지닌다.


LifeCycle Diagram

React에서 생명주기 메소드에 대해 설명할때 사용되는 다이어그램이다. 컴포넌트에서 최종적으로 호출하는 render 함수 전 후로 생명주기 별 메소드 실행 순서를 갖는다.

import React, { Component } from 'react';

export default class Basic extends Component {
    constructor(props) {
        super(props);
        console.log("constructor");
    }

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

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

    componentWillUnmount() {
        console.log("componentWillUnmount");
    }
  
    render() {
        return (
            <div>
            뭐 대강 이런식이라능
            </div>
        );
    }
}

뭐 대충 이런구조인데 각 메소드별로 설명해보겠다.

👽 먼저 React 생명주기에는 세가지 경우가 존재한다.


Mount (생성)

예로 마운트란 디스크와 같은 물리장치의 특정위치를 연결시켜주는 것을 말한다. React의 마운트도 같은 개념이다. 각 컴포넌트를 위치에 맞게 연결시켜주는 절차를 마운트라고 하는데, 이것은 컴포넌트의 생성과 동시에 연결 작업이 이루어지기 떄문에 마운트 단계라고 칭한다.

1. constructor
말그대로 생성자 메소드다. 뭔 짓을 해도 얘가 먼저임

constructor(props) {
    super(props); // super로 부모 컴포넌트의 생성자를 호출해줘야 this 키워드 사용가능
    console.log("constructor");
}

2. getDerivedStateFromProps
getDerivedStateFromPropsprops 로 받아온 것을 state 에 꽂아넣을 때 사용한다. return 타입으로 Javascript Object를 주어야 한다. return된 Object는 state에 반영된다.

💥 메소드 앞에 static 을 필요로 하고, 내부 this 키워드 사용 불가

static getDerivedStateFromProps(nextProps, prevState) {
    console.log("getDerivedStateFromProps");

    if (nextProps.color !== prevState.color) {
      return { color: nextProps.color };
    }

    return null;
}

3. render
컴포넌트 렌더링시 호출되는 메소드다. 모든 클래스형 컴포넌트의 return 타입이다.

render() {
    console.log('render');
  
    return (
       <div>
       뭐 대강 이런식이라능
       </div>
    );
}

4. componentDidMount
컴포넌트의 첫번째 렌더링이 마치고 호출되는 메소드로, 호출되는 시점에는 페이지내 컴포넌트가 화면에 나타난 상태다. 여기선 주로 D3, masonry 처럼 DOM 을 사용해야하는 외부 라이브러리 연동을 하거나, 해당 컴포넌트에서 필요로하는 데이터 fetch를 위한 axios, DOM 속성을 읽어 변경 및 UI 작업이 이루어진다.

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

Updating (갱신)

React에서의 갱신의 개념은 props, state등 상태에 대한 갱신을 말한다. React는 모든 값에 대해 갱신 이벤트를 감지할 수 있으며, 이를 통해 모듈을 분리하고 결합하는 구조를 지닐 수 있다.

1. getDerivedStateFromProps
마운트의 getDerivedStateFromProps 메소드와 동일하다.

2. shouldComponentUpdate
shouldComponentUpdate 메소드는 컴포넌트가 리렌더링 할지 말지를 결정하는 메소드다. true/false로 렌더링을 컨트롤하며, 주로 앱 최적화시 사용하는 메소드다. React.memo와 동일한 기능이다. 이는 추후 포스트에서 다루겠다.

shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate", nextProps, nextState);
    
    // carrots이 아닌 경우 렌더링하지 않음
    return nextState.userName == 'carrots';
}

3. render
마운트의 render 메소드와 동일하다.

4. getSnapshotBeforeUpdate
getSnapshotBeforeUpdate 는 Virtual DOM이 실제 DOM에 반영되기 직전에 실행된다. 이 메서드에선 이전과 현재의 propsstate를 접근가능하다. return된 값은 이후 호출될 componentDidUpdate 3번째 인자로 전달된다.

getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log("getSnapshotBeforeUpdate");

    if (prevProps.color !== this.props.color) {
      return this.myRef.style.color;
    }

    return null;
}

5. componentDidUpdate
componentDidUpdate 는 DOM에 리렌더링 이후 변화가 모두 반영되고 난 뒤 호출되는 메소드로. 3번째 파라미터로 getSnapshotBeforeUpdate 에서 반환한 값을 조회할 수 있다.

componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("componentDidUpdate", prevProps, prevState);
    
    if (snapshot) {
        console.log("업데이트 되기 직전 색상 : ", snapshot);
    }
}

Unmount (삭제)

언마운트는 말그대로 마운트의 반대, 컴포넌트의 연결해제, 즉 컴포넌트의 삭제를 의미한다. document.unload와 같은 이벤트라고 생각하면 쉽다.

1. ComponentWillUnMount
componentWillUnmount 는 DOM에서 컴포넌트가 지워질때 실행된다. $(window).unload와 유사한 기능이다. 컴포넌트와 관련된 것들을 정리하는데 사용한다. 예를 들어 로그아웃시 주 구성 Component를 해제하기 전에 사용자 세부정보와 모든 인증 토큰을 지운다거나 setIntervalclear한다거나 할 수 있다.

💥 ReactV16.3부터 will 이 포함된 메소드는 Deprecated됐으나, 컴포넌트 해제의 경우 componentDidUnmount를 제공할 수 없다. 이미 제거된 컴포넌트에서 이벤트를 발생시킬 수 없기 때문이다.

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

ReactV16.3 이전의 LifeCycle

ReactV16.3 버전 이후로 Deprecated된 메소드가 존재한다.

  • componentWillmount : 컴포넌트 렌더링 직전에 수행
  • componentWillreceiveProps : props 변경 직전에 수행
  • componentWillupdate : 화면 리렌더링 직전에 수행

will 메소드가 Deprecated된 이유 > reactjs.org/blog

요약하자면 React 커뮤니티에서 가장 혼란을 가져오는 LifeCycle기 때문에 없앴다고 한다. 보통 DOM에 대한 제어가 끝난 뒤에 데이터 fetch등이 이루어지는 것이 일반적이다. 그러나 렌더링 직전에 데이터 조회 및 state 변경시 하위 모듈에 끼치는 영향에 대해 추적이 힘든 것이 주된 이유인 것 같다.

👽 그래도 죽어도 써야겠으면 ReactV17부터는 UNSAFE_라는 Prefix를 붙여서 사용해야된다. 어구에서 보다 싶이 불안정하니 쓰지말라는 듯하다. 쓰지말라면 걍 쓰지 말자;;

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

UNSAFE_componentWillreceiveProps(nextProps) {
    console.log('UNSAFE_componentWillreceiveProps', nextProps);
}

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

정리하며

오늘은 React의 컴포넌트 생명주기 메소드, 그중 class형 컴포넌트용 메소드에 대해 알아봤다. Jquery가 만연하던 시절, $(document).ready는 거의 모든 페이지에 필수적으로 사용되었다는 것을 알 것이다. 프론트엔드 개발에 있어 특정 페이지에 대한 생명주기 컨트롤은 그만큼 중요하고 사용빈도가 높다. 그만큼 이해를 정확히 하고 넘어가야 한다고 느낀다.

오늘 저녁은 삼겹볶음이다. 🥕


참고 : https://www.paduckk-dev.com/development/React%20LifeCycle/
https://medium.com/@changmoomoon/react-v16-3-%EC%9D%B4%ED%9B%84-lifecycle-api-%EC%B4%9D-%EC%A0%95%EB%A6%AC-16-3v%EB%B6%80%ED%84%B0-deprecated%EB%90%9C-api%EB%8F%84-%ED%8F%AC%ED%95%A8-37456f843efd
https://react.vlpt.us/basic/25-lifecycle.html
https://velog.io/@st2702/React-Lifecycle-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0

profile
당근먹고 강력한 개발

0개의 댓글