본문 바로가기
FE/React

Class Component & Functional Component

by ideal_string 2022. 10. 1.

리액트는 컴포넌트로 이뤄져있다. 컴포넌트로 시작해 컴포넌트로 끝난다 해도 과언이 아니다. 이 컴포넌트를 만드는 데 두 가지 방식이 있다. 클래스 컴포넌트(Class Component)와 함수 컴포넌트(Functional Component)다. 결론부터 말하면 여러 이유로 함수 컴포넌트가 더 낫다.

Class Component

리액트가 처음 세상에 나타났을 때 컴포넌트는 클래스형 컴포넌트가 장악했다. 이 클래스는 물론 자바스크립트에 있는 그 클래스에서 가져왔다. 사용 방식도 거의 같다. 

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

클래스 컴포넌트가 많이 쓰인 이유는 정교한 작업을 할 수 있었기 때문이다. 리액트 초창기엔 lifecycle 조절, state 사용은 클래스 컴포넌트만 가능했다. state를 쓰지 않는 경우에 한해서만 함수형 컴포넌트를 사용했다고 할 정도다. 그러나 hook이 업데이트 되면서 상황이 달라졌다.

 

Functional Component

리액트에서 2018년은 hook의 해이자, 함수형 컴포넌트의 해다. hook의 등장으로 함수형 컴포넌트가 재조명을 받았기 때문. 클래스 컴포넌트에서만 사용할 수 있던 lifecycle(useEffect), state(useState) 등을 함수형에서도 쓸 수 있게 되었다.

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

함수 컴포넌트는 constructor나 render()를 작성할 필요 없어 간결한데다, props로 값을 넘기고 받을 수 있다. 함수 컴포넌트의 단점으로 여겨진 게 없어진 지금 페이스북에서도 함수 컴포넌트 사용을 권장하고 있다. 

 

특징 요약

Class Component   Functional Component
class 키워드 필요 class 대비 메모리 사용량 적음
extends Component 상속 필요 함수 만드는 모든 방법으로 사용 가능
render() 필수 props 사용 가능
state, setState 사용(객체 형식) useState 사용(함수 형식)
lifecycle(componentDidMount, componentDidUpdate, componentWillUnmount 등) 사용 가능 lifecycle(useEffect) 사용 가능
임의 메서드 생성 가능  

 

사용 비교

import { Component } from "react";

export default class ClassCounterPage extends Component {
  state = {
    count: 0,
  };

  componentDidMount() {
    console.log("그려지고 나서 실행");
  }

  componentDidUpdate() {
    console.log("변경되고 나서 실행");
  }

  componentWillUnmount() {
    console.log("사라질 때 실행");
  }

  onClickCountUp = () => {
    this.setState((prev: { count: number }) => ({ count: prev.count + 1 }));
  };

  render() {
    return (
      <>
        <div>{this.state.count}</div>
        <button onClick={this.onClickCountUp}>카운터 올리기</button>
      </>
    );
  }
}

클래스 컴포넌트

import { useEffect, useState } from "react";

export default function FunctionCounterPage() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("그려지고 나서 실행");
  }, []);

  useEffect(() => {
    console.log("count가 변경되고 나서 실행");
  }, [count]); 

  useEffect(() => {
    return () => {
      console.log("사라질 때 실행");
    };
  }, []);

  const onClickCountUp = () => {
    setCount((prev) => prev + 1);
  };

  return (
    <>
      <div>{count}</div>
      <button onClick={onClickCountUp}>카운터 올리기</button>
    </>
  );
}

함수형 컴포넌트

 

마무리

클래스 컴포넌트와 함수 컴포넌트를 단순 비교해도 함수 컴포넌트가 낫다. 메모리를 적게 먹는 것 뿐만 아니라, 코딩을 작성할 때 코드 길이와 다른 컴포넌트로 props를 넘길 때도 함수 컴포넌트가 사용하기 훨씬 수월하기 때문이다. 클래스 컴포넌트는 class에 대한 이해, this 바인딩에 대한 이해가 기본이기 때문에 초보자들이 쉽게 이해하기 어려운 측면이 있다. 이런 상황에서 클래스 컴포넌트를 꼭 써야만 하는 이유가 있다면 어떻게든 더 잘 활용할 방법을 찾을텐데, 페이스북에서 조차 함수 컴포넌트를 권장하고 있기에 이런 특징이 있다고만 이해하고 넘어간다.

몇몇 커뮤니티나 부트캠프 관련 이야기들을 들어보면 아직 클래스 컴포넌트로 쓰여진 코드가 있는 회사들이 있을 수 있으니 알아두는 게 좋다고들 한다. 코드를 보고 당황하지 않아야 하고, 혹은 클래스 컴포넌트를 함수 컴포넌트로 바꿔야하는 일을 맡게 될 수도 있으니까.

※ 잘못된 내용이 있을 경우 댓글로 알려주세요. 배우고 익히고 수정하겠습니다:)

'FE > React' 카테고리의 다른 글

전역 상태 관리  (0) 2022.10.09
Lifecycle(feat. DOM)  (0) 2022.10.03
useEffect  (1) 2022.09.30
useRef  (0) 2022.09.29
state Lifting  (0) 2022.09.26