클래스 컴포넌트

zoe·2024년 6월 20일

개발용어

목록 보기
10/12
post-thumbnail

프롤로그

React 컴포넌트를 만들 때, 클래스형 컴포넌트, 함수형 컴포넌트 2가지 방법이 있다.
구글링을 하면서 찾아본 리액트 예제들만 봐도 함수형이 많은 거 같은데, 그럼 왜 이렇게 흐름이 달라졌을까? 그 이유은 2019 v16.8부터 함수형 컴포넌트에 리액트 훅(hook)을 지원하면서, 공식 문서에서도 함수형 컴포넌트와 훅 사용을 권장하고 있다.
그렇다면 클래스 컴포넌트가 무엇이고, 함수형과 차이점은 무엇일지에 대해 알아보자

클래스 컴포넌트란?

일단 클래스 컴포넌트는 ES6의 클래스를 사용해 작성한다. 또한 extends 키워드를 이용하여 React.Component 클래스를 상속받으며, render() 메소드를 이용해서 UI를 정의한다.

클래스 컴포넌트는 state와 props를 이용하여 상태를 관리한다. state는 컴포넌트 내부에서 관리되는 상태이며, setState() 메소드를 이용하여 업데이트를 할 수 있다.
props는 부모 컴포넌트에서 전달되는 데이터를 의미한다.

함수형 컴포넌트

함수형 컴포넌트는 ES6 함수나 화살표 함수를 사용하여 작성한다. return 문을 이용하여 UI를 정의한다.

함수형 컴포넌트에서는 부모 컴포넌트에서 전달되는 데이터인 props를 이용하여 상태를 관리한다. 이런 상태를 관리하기 위해 useState Hook을 사용한다.

선언 방식

  • 아래는 클래스형 컴포넌트의 기본 구조이다.
import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  incrementCount = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.incrementCount}>Increment</button>
      </div>
    );
  }
}

export default Counter;

위 코드에서 Counter 클래스를 이용하여, 컴포넌트를 정의하고 state를 이용하여 count 값을 관립니다. incrementCount() 메소드를 이용하여 버튼 클릭 시 count 값을 업데이트합니다. render() 메소드에서 UI를 정의한다.

  • 아래는 함수형 컴포넌트의 예시이다.

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const incrementCount = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={incrementCount}>Increment</button>
    </div>
  );
};

export default Counter;

useState 훅을 사용하며, count 상태를 정의하고, setCount 함수를 사용하여 상태를 업데이트한다. 여기서 incrementCount 함수는 setCount를 호출하여 count 값을 증가시키는 역할을 한다.

생명주기 메서드 & 상태관리

componentDidMount: 컴포넌트가 마운트된 직후에 호출되며, 보통 초기 데이터 로드 등에 사용된다.
componentDidUpdate: 컴포넌트가 업데이트된 직후에 호출되며, 상태나 props가 변경된 후 작업을 수행할 때 유용하다.
componentWillUnmount: 컴포넌트가 언마운트되기 직전에 호출되며, 정리 작업 (예: 타이머 해제) 등에 사용된다.

  • 클래스형 컴포넌트 사용 방식
import React, { Component } from 'react';

class Timer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      seconds: 0
    };
  }

  componentDidMount() {
    this.interval = setInterval(() => {
      this.setState((prevState) => ({
        seconds: prevState.seconds + 1
      }));
    }, 1000);
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState.seconds !== this.state.seconds) {
      console.log(`Timer updated: ${this.state.seconds} seconds`);
    }
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return (
      <div>
        <h1>Timer: {this.state.seconds} seconds</h1>
      </div>
    );
  }
}

export default Timer;

클래스형 컴포넌트는 this.state 객체를 사용하여 seconds 상태를 0으로 초기화하고, this.setState를 사용하여, 상태를 관리한다.

componentDidMount는 컴포넌트가 처음으로 DOM 에 마운트된 후 실행되며, setInterval로 1초마다 setState를 호출하여 seconds 상태를 1씩 증가시키는 타이머를 설정한다. 이 타이머의 id는 this.interval에 저장된다.

componentDidUpdate는 컴포넌트가 업데이트 된 후 실행되는데, 업데이트는 상태나 props가 변경될 때 발생한다. 이전 상태의 seconds 와 현재 상태의 seconds를 비교하고, 상태가 변경된 경우에만 로그를 출력한다.

componentWillUnmount는 컴포넌트가 DOM에서 제거되기 직전에 실행되며, clearInterval 을 사용하여 타이머를 정리한다. 이를 통해 메모리 누수를 방지한다.

import React, { useState, useEffect } from 'react';

const Timer = () => {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(prevSeconds => prevSeconds + 1);
    }, 1000);

    return () => clearInterval(interval); // Cleanup function
  }, []); // Empty dependency array means this effect runs once after initial render

  useEffect(() => {
    console.log(`Timer updated: ${seconds} seconds`);
  }, [seconds]); // This effect runs every time the seconds state changes

  return (
    <div>
      <h1>Timer: {seconds} seconds</h1>
    </div>
  );
};

export default Timer;

함수형 컴포넌트는 useState와 useEffect 훅을 사용하여 동일한 기능을 구현한다. useEffect 훅은 컴포넌트가 마운트될 때와 seconds 상태가 변경될 때 실행되며, return () => {} 안에 clearInterval 을 사용하여 타이머를 정리하는 부분도 작성했다. 또한 useState를 사용하여 상태를 관리한다.

차이점

위를 토대로 둘의 차이점을 비교해보자!

  1. 선언 방법

    • 클래스형 컴포넌트 : ES6 클래스 문법을 사용하여, React.Component 를 상속받아 구현
    • 함수형 컴포넌트 : 일반 함수(화살표 함수)로 작성되며, 별도의 클래스 상속없이 구현
  2. 상태 관리

    • 클래스형 컴포넌트 : this.state와 this.setState를 사용하여 상태를 관리
    • 함수형 컴포넌트 : useState Hook을 사용하여 상태를 관리
  3. 라이프사이클 메서드

    • 클래스형 컴포넌트 : 라이프사이클 메서드를 사용하여 컴포넌트의 생성, 업데이트, 제거 로직을 구현
    • 함수형 컴포넌트 : useEffect Hook을 사용하여 라이프사이클 메서드와 유사한 기능을 구현

장단점

특성클래스형 컴포넌트함수형 컴포넌트
코드의 간결함길고 복잡함간결하고 짧음
상태관리this.state와 setState를 사용useState와 useReducer 를 사용
생명 주기useEffect를 사용componentDidMount, componentDidUpdate, componentWillUnmount 등 사용

결론

함수형 컴포넌트는 최신 React 개발에서 많이 사용되고 있는 추세이며, 간결하고 이해하기 쉬운 코드 작성이 가능하다. 반면 클래스형 컴포넌트는 생명주기 메서드를 명시적으로 사용할 수 있어,함수형 컴포넌트를 사용하지 않을 이유를 찾기가 어렵다는 생각이 든다.

그러나 레거시 코드를 리펙토링할 때 사용되기도 하며, 다양한 회사에서 아직 사용할 수 있기 때문에, 사용 방식정도는 알아두어야 할 것 같다.

참고자료

profile
코당탕탕 성장기

0개의 댓글