React - State과 Life Cycle

milkbottle·2023년 12월 31일
0

React

목록 보기
7/33

저 두 단어가 뭐야?

상태라는 말이다. 프론트엔드 개발에 있어 가장 많이 듣는 단어이다.

OOO님 상태관리 라이브러리는 어떤거 쓰시나요?

사실 프론트엔드 개발뿐만 아니라, 앱 개발에 있어서도 쓰이는 단어이다.

심지어 게임 개발 분야에서도 이 상태관리는 매우 중요하다.

이해를 쉽게 하기 위해 예를 들어보자.

그 예시

  1. 현재 내 카드에는 2,000원이 있다.

  2. OO 편의점에서 육O장 컵라면을 1,100원을 주고 사먹었다.

  3. 그리고 친구와 피시방에 가서 아레나 1시간을 땡기려고 1,000원을 충전하려고 한다.

  4. 그런데 돈이 없어서 키오스크에서 "잔액이 부족합니다 ㅋ"라고 한다.

이 Flow를 그려내려면 어떤게 필요할까?

바로 이런 과정 하나하나에 내 카드 잔고에 대한 최신화를 해줘야할 것이다.

내 카드의 잔액 값이 들어있는 것이 State이고,

이를 주기적으로 업데이트해주는 것이 Life Cycle이 해줘야할 덕무라고 볼 수 있다.

Life Cycle

생명주기라는 말이다. React Component는 모두 생명주기라는 것이 존재한다.

처음에 컴포넌트가 생성되었을 때, 컴포넌트가 업데이트(최신화)되었을 때, 컴포넌트가 사라졌을 때이다.

사실은 생명주기가 더 다양하지만, 저 3가지가 모든 것 중에서 중요하다.

실시간으로 무언가를 다루는 모든 곳에서 생명주기라는 것이 존재하는데 무조건 중요하다.

뭐 소켓통신에서는 소켓을 열고, 이를 주기적으로 받으려고 recv를 하고, 마지막으로 소켓을 닫고.. 이런식으로 무조건 생, 최신화, 사 이렇게 3가지만 알면 된다.

여담이 길었고.. React Life Cycle은 공식문서에서 이렇게 표현한다.

Mounting

컴포넌트의 생성이다.

컴포넌트를 처음 만들고 render를 할 때, componentDidMount라는 함수가 제일 먼저 실행된다.

Updating

컴포넌트의 업데이트이다.

컴포넌트를 생성하고 특정한 상황에서 State를 변경하거나 새로운 props가 바뀌거나,

아예 강제로 업데이트(forceUpdate())할 때, componentDidUpdate라는 함수가 실행된다.

Unmounting

컴포넌트가 사라지는 것이다.

컴포넌트가 더 이상 화면에 표시되지 않을 때, componentWillUnmount라는 함수가 실행된다.

setState와 응용하기

앞서 언급한 componentDidMount, componentDidUpdate, componentWillUnmount함수는

Class형 Component에서 오버라이딩 하여 정의할 수 있다.

import React from "react";

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

        this.state = {};
    }

    componentDidMount() {
        console.log(`${this.props.id} componentDidMount() called.`);
    }

    componentDidUpdate() {
        console.log(`${this.props.id} componentDidUpdate() called.`);
    }

    componentWillUnmount() {
        console.log(`${this.props.id} componentWillUnmount() called.`);
    }

    render() {
        return (
            <div >
                <span >{this.props.value}</span>
            </div>
        );
    }
}

export default Block;

이렇게 Block이라는 컴포넌트를 정의한다.

State클래스형 컴포넌트의 생성자에서 정의한다.

import React from "react";
import Block from "./Block";

const blockInfoList = [
    {
        id: 1,
        value: "리액트",
    },
    {
        id: 2,
        value: "스프링",
    },
    {
        id: 3,
        value: "장고",
    },
];

var timer;

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

        this.state = {
            blocks: [],
        };
    }

    componentDidMount() {
        const { blocks } = this.state;
        timer = setInterval(() => {
            if (blocks.length < blockInfoList.length) {
                const index = blocks.length;
                blocks.push(blockInfoList[index]);
                this.setState({
                    blocks: blocks,
                });
            } else {
                this.setState({
                    blocks: [],
                });
                clearInterval(timer);
            }
        }, 1000);
    }

    componentWillUnmount() {
        if (timer) {
            clearInterval(timer);
        }
    }

    render() {
        return (
            <div>
                {this.state.blocks.map((block) => {
                    return (
                        <Block
                            key={block.id}
                            id={block.id}
                            value={block.value}
                        />
                    );
                })}
            </div>
        );
    }
}

export default BlockList;

blockInfoList는 블록에 들어갈 props의 값을 저장하는 리스트이다.

id, value를 저장한 객체를 리스트로 가지고 있다.

BlockListBlock컴포넌트를 리스트로 그려주고 이를 1초 단위로 최신화시켜주는 컴포넌트이다.

BlockList는 최초로 생성되었을 때, setInterval함수를 통해 1초마다 setState가 실행된다.

setState함수를 통해 BlockList컴포넌트 객체는 자신 스스로의 상태(Block의 id, value의 리스트를 저장)를 변경한다.

변경이 되면 자동으로 리액트가 컴포넌트들을 갱신시키기 때문에,

Block컴포넌트가 갱신되어 Block컴포넌트의 componentDidUpdate함수가 실행된다.

함수형 컴포넌트 vs 클래스형 컴포넌트

사실 이전의 컴포넌트 부분에서 함수형 컴포넌트와 클래스형 컴포넌트에 대한 설명을 하지 않았다.

간단히 말하면 대부분 함수형 컴포넌트를 사용한다.

위의 코드를 보면 알겠지만, 클래스형 컴포넌트는 너무 가독성이 떨어진다.

클래스형 컴포넌트를 응용해서 만든 것이 함수형 컴포넌트이다.

함수형 컴포넌트도 리액트 코어를 까보면 클래스형 컴포넌트를 응용해 만든 것이기 때문이다.

그래서 실제로는 클래스형 컴포넌트가 함수형 컴포넌트보다 성능이 더 좋을 수 밖에 없고, 기능 자체도 low level이지만, 응용한다면 더 다양하게 쓸 수도 있다.

그러나 Hooks라는 방법이 등장하여 아래의 표처럼 사용될 수 있다.

지극히 개인적인 의견입니다

요즘은 개발자 경험이 중요하기 때문에 가독성과 유지보수 부분을 크게 평가하는 듯 하다.

클래스형 컴포넌트가 더 성능이 좋은데 굳이 왜 함수형 컴포넌트를 만들었을까.. 생각해보니

어? 함수형 컴포넌트로 간단히 만들자!!

한 단계 응용해서 만든 거니까 성능이 떨어지잖아!! >> 기존의 클래스형처럼 되도록 개선해!!

상태관리 부분은 많이 복잡해지는데요..? >> 응 그냥 Hooks라는 것을 만들어서 되게 해!!

뭐 이러지 않았을까? 라고 감히 생각해본다.

아무튼 우리가 편해졌으니 된거 아닐까? 가독성 만세!!ㅎㅎ

참고

0개의 댓글