[React] 가상돔, 라이프 사이클, 클래스 컴포넌트
본문 바로가기
프레임워크/React

[React] 가상돔, 라이프 사이클, 클래스 컴포넌트

by 은돌1113 2021. 11. 15.

라이프 사이클

: 컴포넌트가 웹페이지에 들어갔다가 사라지기까지의 과정을 말한다.

 

1) 가상돔이란?

-> 바뀐 부분만 진짜 DOM에 반영하는 것

->  메모리에 올라가 있는 눈에 보이지 않는 가짜 DOM에 변경 사항을 전부 넣어서마지막에 진짜 DOM에는 한번만 반영하는 것

 

: DOM은 html 단위 하나하나를 객체로 생각하는 모델입니다

예를 들면, 'div'라는 객체는 텍스트 노드, 자식 노드 등등, 하위의 어떤 값을 가지고 있겠죠?

이런 구조를 트리 구조라고 합니다. DOM이 트리구조란 소리입니다. 

 

DOM 트리 중 하나가 수정될 때마다 모든 DOM을 뒤지고, 수정할 걸 찾고, 싹 수정을 한다면?

→ 필요없는 연산이 너무 많이 일어난다!

→ 그래서 등장한 게 가상돔!

 

가상돔은 메모리 상에서 돌아가는 가짜 DOM입니다.

 

가상돔의 동작 방식: 기존 DOM과 어떤 행동 후 새로 그린 DOM(가상 돔에 올라갔다고 표현합니다)을 비교해서

정말 바뀐 부분만 갈아끼워줍니다! → 돔 업데이트 처리가 정말 간결하죠!

 

그럼 어떤 행동을 해야 진짜 DOM을 새로 그릴까요?

- 처음 페이지 진입했을 때도 그리겠죠!

- 데이터가 변했을 때도 그릴 겁니다! (가짜 DOM에서 바뀐 부분을 찾아서 반영을 해줄 때)

 

+ 알면 덜 찜찜한 이야기: DOM이 정말 그렇게 느려? 반은 맞고 반은 틀려요.

DOM은 사이트 구조에 따라 가상돔을 쓰는 것보다 훨씬 성능이 좋을 수 있고(=빠를 수 있고),

속이 터지게 느릴 수 있습니다.

 

2) 라이프 사이클이란?

: 컴포넌트의 라이프 사이클(= 컴포넌트 생명주기)은 정말 중요한 개념입니다!

컴포넌트가 렌더링을 준비하는 순간부터, 페이지에서 사라질 때까지가 라이프 사이클이에요.

 

(공식 문서에서 자세히 다루고 있습니다.)

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

 

State and Lifecycle – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

아래 도표는 어떻게 라이프 사이클이 흘러가는 지에 대한 도표입니다.

컴포넌트는 생성되고 → 수정(업데이트)되고 → 사라집니다.

 

-> 생성(mount)은 처음으로 컴포넌트를 불러오는 단계입니다.

-> 수정(업데이트, update)는 사용자의 행동(클릭, 데이터 입력 등)으로 데이터가 바뀌거나,

부모 컴포넌트가 렌더링할 때 업데이트 됩니다. 아래의 경우죠!

    -> props가 바뀔 때 (props -> 부모가 자식에게 주는 데이터)

    -> state가 바뀔 때 (state -> 내가 가진 데이터)

    -> 부모 컴포넌트가 업데이트 되었을 때(=리렌더링했을 때)

    -> 또는, 강제로 업데이트 했을 경우! (forceUpdate()를 통해 강제로 컴포넌트를 업데이트할 수 있습니다.)

-> 제거(unmount)는 페이지를 이동하거나, 사용자의 행동(삭제 버튼 클릭 등)으로 인해 컴포넌트가 화면에서 사라지는 단계입니다.

 

2) 라이프 사이클 함수(메소드)로 보는 라이프 사이클

 

라이프 사이클 함수는 클래스형 컴포넌트에서만 사용할 수 있습니다.

 

라이프 사이클을 아는 건 중요한데 왜 우리는 클래스형 컴포넌트보다 함수형 컴포넌트를 많이 쓰냐구요?

리액트 공식 매뉴얼에서 함수형 컴포넌트를 더 권장하기 때문입니다!

(리액트 16.8버전부터 등장한 React Hooks으로 라이프 사이클 함수를 대체할 수 있거든요.)

import React from "react";

// 클래스형 컴포넌트는 이렇게 생겼습니다!
class LifecycleEx extends React.Component {

// 생성자 함수
  constructor(props) {
    super(props);
    
    this.state = {
      cat_name: '나비',
    };

    console.log('in constructor!');
  }

  changeCatName = () => {
    // 다음 강의에서 배울, state 업데이트 하는 방법입니다!
    // 지금은 componentDidUpdate()를 보기 위해 쓰는 거니까, 처음보는 거라고 당황하지 말기!
      this.setState({cat_name: '바둑이'});

      console.log('고양이 이름을 바꾼다!');
  }

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

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

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

  // 랜더 함수 안에 리액트 엘리먼트를 넣어줍니다!
  render() {

    console.log('in render!');

    return (
      <div>
          {/* render 안에서 컴포넌트의 데이터 state를 참조할 수 있습니다. */}
        <h1>제 고양이 이름은 {this.state.cat_name}입니다.</h1>
        <button onClick={this.changeCatName}>고양이 이름 바꾸기</button>
      </div>
    );
  }
}

export default LifecycleEx;

 

- constructor()

: 생성자 함수라고도 부릅니다. 컴포넌트가 생성되면 가장 처음 호출되는 친구죠!

 

- render()

: 컴포넌트의 모양을 정의하는 친구입니다!

여기에서도 state, props에 접근해서 데이터를 보여줄 수 있어요.

리액트 요소를 return에 넣어 반환해줬던 거 기억하시죠?

render() 안에 들어갈 내용은 컴포넌트의 모양에만 관여하는 것이 가장 좋습니다.

즉, state나, props를 건드려 데이터를 수정하려고 하면 안됩니다!

 

- componentDidMount()

: 컴포넌트가 화면에 나타나는 것을 마운트(Mount)한다고 표현합니다.

didMount()는 마운트가 완료 되었다는 소리겠죠?

이 함수는 첫번째 렌더링을 마친 후에만 딱 한 번 실행됩니다. 컴포넌트가 리렌더링할 때는 실행되지 않아요.

보통은 이 안에서 ajax 요청, 이벤트 등록, 함수 호출 등 작업을 처리합니다.

또, 이미 가상돔이 실제돔으로 올라간 후니까 DOM 관련 처리를 해도 됩니다!

 

- componentDidUpdate(prevProps, prevState, snapshot)

: DidMount()가 첫 렌더링 후에 호출 되는 함수라면, DidUpdate()는 리렌더링을 완료한 후 실행되는 함수입니다.

이 함수에 중요한 파라미터가 2개 있는데, prevProps와 prevState입니다. 각각 업데이트 되기 전 props, state예요.

이전 데이터와 비교할 일이 있다면 가져다 쓰도록 합시다.

DidUpdate()가 실행될 때도 가상돔이 실제돔으로 올라간 후니까 DOM 관련 처리를 해도 됩니다!

 

- componentWillUnmount()

: componentWillUnmount()가 호출되는 걸 보려면, app.js에서 <LifecycleEx/>를 없애봐야겠죠?

삼항연산자를 사용해서 컴포넌트를 보여주거나, 없애는 걸 조건부 렌더링이라고 불러요.

 

댓글