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

.·2025년 1월 8일
post-thumbnail

리액트 컴포넌트

지금은 거의 모든 리액트 강의에서 리액트 코드를 작성할 때 함수형 컴포넌트로 구현한다.
이는 React에서 더이상 클래스형 컴포넌트가 아닌 함수형 컴포넌트를 권장하기 때문이다.
오늘은 이 둘의 어떤 차이가 있었고 기존에 클래스 컴포넌트에서는 어떠한 문제점이 있었길래
함수형 컴포넌트로 대체가 되는 흐름으로 바뀌었는지 알아볼 예정이다.

🚨 클래스형 컴포넌트의 한계

아래는 기존 클래스형 컴포넌트의 예시 코드이다.

import React, { Component } from 'react';

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

    // this 바인딩
    this.increment = this.increment.bind(this);
  }

  increment() {
    this.setState((prevState) => ({
      count: prevState.count + 1,
    }));
  }

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

export default ClassComponent;

위 코드에서 보여주는 클래스형 컴포넌트의 단점은 다음과 같다.

1. 구문이 복잡함 : 클래스형 컴포넌트는 클래스 문법을 사용하므로, 상태 관리와 생명주기 메서드를 다루는 것이 다소 복잡할 수 있습니다.

2. this 바인딩 문제 : 메서드에서 this를 사용할 때 바인딩이 필요해, 실수로 this가 undefined가 되는 경우가 발생할 수 있다.

3. 코드 중복 : 여러 컴포넌트에서 동일한 생명주기 메서드를 사용한다고 할지라도 새롭게 정의해주어야 한다. 상속을 사용한다고 할지라도 여러 단계에서 상속할 경우 어떤 메서드가 어디서 정의되었는지 추적하기가 어렵다.

4. 상태 관리 어려움 : 상태를 관리하기 위해 여러 메서드를 정의해야 한다.

💡 함수형 컴포넌트의 hooks 패턴 등장

함수형 컴포넌트는 리액트 16.8 버전부터 도입된 Hooks를 활용하여 컴포넌트에서 클래스에서 메소드를 정의해 사용했던 상태와 생명주기 기능을 사용할 수 있게 되었고 이를 통해 개발자는 더욱 간결하고 효율적인 코드를 작성할 수 있게 되었다.

함수형 컴포넌트의 장점

1. 간결한 구문: 함수형 컴포넌트는 클래스 문법을 사용하지 않기 때문에 상태 및 생명주기 메서드를 Hooks를 통해 간단하게 구현할 수 있다. 이는 코드의 가독성을 높이고 유지보수를 용이하게 만든다.

import React, { useState } from 'react';

const FunctionComponent = () => {
  const [count, setCount] = useState(0); // 상태 선언

  const increment = () => {
    setCount(prevCount => prevCount + 1); // 상태 업데이트
  };

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

2. this 바인딩 문제 없음: 함수형 컴포넌트에서는 this를 사용하지 않기 때문에 바인딩 문제에 대한 걱정이 없다. 이로 인해 코드가 더욱 직관적이고 간단해진다.

3. 상태 관리의 유연성: Hooks를 사용하면 여러 상태를 쉽게 관리할 수 있으며, useReducer와 같은 Hooks를 통해 복잡한 상태 로직도 간단하게 처리할 수 있다.

4. 재사용성: 커스텀 Hooks를 만들어 공통된 상태 로직이나 비즈니스 로직을 재사용할 수 있다. 이를 통해 코드 중복을 줄이고 유연성을 높일 수 있다. 예를 들어, 다음과 같이 커스텀 Hook을 정의하고 사용할 수 있다.

const useCounter = () => {
  const [count, setCount] = useState(0);
  const increment = () => setCount(prevCount => prevCount + 1);
  return { count, increment };
};

const ComponentA = () => {
  const { count, increment } = useCounter();
  return <div onClick={increment}>Count A: {count}</div>;
};

const ComponentB = () => {
  const { count, increment } = useCounter();
  return <div onClick={increment}>Count B: {count}</div>;
};

결론

이러한 이유들로 인해 리액트 자체에서도 더이상 클래스형 컴포넌트보다는 함수형 컴포넌트의 Hooks로의 전환을 적극적으로 권장하고 있다. 함수형 컴포넌트의 코드가 더 간결하고 가독성이 높으며, 복잡한 상태 관리나 생명주기 처리 또한 더욱 쉽게 짤 수 있기 떄문이다.

profile
.

0개의 댓글