본문 바로가기

오픈소스/노드

[Node] React 정리(3) - 생명주기와 상태 저장을 통한 화면 렌더링

리액트로 프로젝트를 생성하여 개발하는 과정 중 리액트의 필수 문법 및 기초적인 부분, 심화 과정 등을 정리한 문서입니다. 정리한 부분에는 제가 이해하는 관점에서만 정리를 하였기 때문에 초점은 보여주는 형식이 아닌 제가 필요할 때 사용하려는 목적이 담겨져 있습니다. 이 문서는 어떠한 리액트의 이론을 다루는 것이 아닙니다. 또한 현재 정리하려는 것은 여러분이 필요한 JSX 부분이 아닐 수 있음을 알려드립니다.

 

 본 과정에서는 차례대로 난이도가 증가하는 정리를 하지 않았습니다. 필요한 부분만을 사용하거나 훑어보는 용도로 사용하시기 바랍니다.

 

 

# Contents


  • 생명 주기
  • 예제 코드

 

 

# 생명 주기


 리액트를 사용할 때에는 생명주기를 알아야 하는 게 필수이긴 합니다만.. 지원하는 함수도 많고 사이클도 많아서 실무에서 적용하고 이해하기 쉬운 사이클만을 이야기하고자 합니다. 생명주기에 대해 간단하게 알아보겠습니다.

 

리액트는 컴포넌트 기반의 View를 중심으로 한 라이브러리입니다.
그러다보니 각각의 컴포넌트에는 라이프사이클 즉, 컴포넌트의 수명 주기가 존재하게 되는데, 컴포넌트의 수명은 보통 페이지에서 렌더링되기 전인 준비 과정에서 시작하여 페이지에서 사라질 때 끝이 나게 됩니다.

 

 

 

마운트는 DOM이 생성되고 웹 브라우저 상에서 나타나는 것을 뜻하고, 반대로 언마운트는 DOM에서 제거되는 것을 뜻하게 됩니다. 주의하여 볼 것은 업데이트 부분인데, 업데이트는 다음과 같은 4가지 상황에서 발생합니다.

 

  1. props가 바뀔 때
  2. state가 바뀔 때
  3. 부모 컴포넌트가 리렌더링 될 때
  4. this.forceUpdate로 강제로 렌더링을 트리거할 때

 


 

Mount

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

 주의할 점은, componentWillMount에서는 props나 state를 바꾸면 안 됩니다.

 

 componentDidMount 에서는 DOM에 접근할 수 있습니다. 

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

 

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

 

Props Update

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

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

주의사항이 있는데, componentWillUpdate에서는 state를 바꿔서는 안 됩니다.

 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

 

생명주기의 관한 내용은 https://www.zerocho.com/category/React/post/579b5ec26958781500ed9955 를 참고하였습니다.

 

 

# 예제 코드


 처음에 페이지로 이동하게 되면 로딩이라는 글자 render 시키면서 5초간 로딩됩니다. 그러다가 로딩이 끝나면 버튼을 render 시키고 그 버튼을 클릭하면 다시 로딩을 render 시키는 간단한 코드입니다.

 

index.js

 

import react from "react";
import reactDOM from "react-dom";
import htm from "htm";
import { TestApp } from "./TestApp.js";

const html = htm.bind(react.createElement);

reactDOM.render(html`<${TestApp} query="development" />`, document.getElementById("root"));

 

 TestApp.js

 

import react from "react";
import htm from "htm";

var html = htm.bind(react.createElement);

export class TestApp extends react.Component {
    constructor(props) {
        super(props);
        this.state = {
            loading: true,
            commercial: false,
        };
    }

    componentDidMount() {
        this.loadData();
    }

    componentDidUpdate(prevProps) {
        if (this.state.loading == "test") {
            this.loadData();
        }
    }

    loadData() {
        this.setState({ loading: true });
        setTimeout(() => {
            this.setState({
                loading: false,
                commercial: false,
            });
        }, 5000);
    }

    render() {
        if (this.state.loading) {
            return html`loading ...`;
        }

        return html`success... <button key="first" onClick=${this.changeState.bind(this)}>클릭해보세요</button>`;
    }

    changeState(e) {
        e.preventDefault();

        this.setState({
            loading: "test",
            commercial: false,
        });
    }
}