React

[React] Class Component와 Functional Component의 차이

킹우현 2023. 2. 11. 22:58

클래스형 컴포넌트(Class Component)

class App extends Component {
  render() {
    return <div>안녕!</div>
  }
}

기존의 React는 Class Component를 기반으로 작업했다.

 

Class Component를 이용해 만들어낸 컴포넌트는 말그대로 하나의 객체처럼 동작할 것이다. 

this 를 통해 자기 자신을 칭하고, 뭔가 변화가 생기면 render() 메서드를 다시 호출해 리랜더링을 할 것이다.

 

그런데 객체를 사용할 때면 매번 언급되는 문제점이 있다. 객체를 이용한 프로그래밍 방식에서는 객체가 가지고 있는 상태와 메서드가 적절히 어우러지도록 설계한다.

이런 구조에서 메서드의 결과물은 상태의 영향을 받게 되는데, 상태에 따라 그 결과 값이 의도치 않게 변한다는 점이 문제점이 있었다.

 

함수형 컴포넌트(Functional Component)

const App = ({ name }) => {
  return (<div>{`안녕! ${name}`}</div>)
};

이러한 Class Component의 단점을 해결해주기 위해 '불변성(Immutable)'이라는 특징을 가지는 Functional Component가 등장하였다.

 

함수형 컴포넌트는 React 컴포넌트가 함수의 결과값으로 반환되는 방식이다.

 

위의 App에서 받아오는 매개변수인 name 은 그대로 변하지 않는다. 일단 이 함수형 컴포넌트가 다시 랜더링, 즉 다시 호출되기 전까지는 name 은 그대로다. 

시작과 끝이 있는 한 흐름의 결과물로 컴포넌트가 만들어지기 때문에 중간에 생길 의도치 않은 변화를 방지할 수 있고, 그 내용을 바꾸기 위해서는 새로운 매개변수 값을 넣어서 다시 호출(리랜더링)해야 한다.

 

따라서 this가 가지고 있는 값이 어떻게 변할지 모르는 클래스형 컴포넌트와 달리, 함수형 컴포넌트는 어떠한 값이 불변하다는 확신을 가지고 구현할 수 있다.

👉🏻 이는 개발자가 의도한 대로 동작할 가능성을 높이고, Side Effect를 줄여준다 !

 

즉, Functional Component는 함수형 프로그래밍의 장점인 '순수성', '불변성'을 이용할 수 있기에 Class Component가 가지고 있는 여러 문제를 줄여준다. ⭐️⭐️⭐️

 

위에서 말한 장점으로 인해, 많은 개발자들이 Functional Component를 활용하고 싶어했으나, 기존의 Class Component를 대체하기엔 무리가 있었다.

 

이는 Class Component가 다음과 같은 강력한 몇가지 기능을 제공하고 있기 때문이었다.

 

1. state와 setState를 이용하여 상태를 관리할 수 있고, 리렌더링이 용이하다.

class App extends Component {
  state = { name: '' }
  setName(value) {
    this.setState({ name: value });
  }
  render() {
    return <div>{this.state.name}</div>
  }
}

 

위처럼 state 에 우리가 원하는 변수를 담은 객체를 두고, setState 를 이용해 해당 객체를 계속 변경해준다.

 

2. 컴포넌트의 Life Cycle에 맞춰 우리가 원하는 명령을 낼 수 있다.

class App extends Component {
  state = { name: '' }
  componentDidMount() {
    this.setState({ name: value });
  }
  render() {
    return <div>{this.state.name}</div>
  }
}

Mount는 컴포넌트가 처음 랜더링되는 과정을 말하는건데, 이 componentDidMount 에 넣어둔 명령은 컴포넌트가 다 만들어지고 나면 불리게 된다.

 

Functional Component는 랜더링할 때마다 함수가 새롭게 불리는 만큼, 위에서 말한 상태 관리가 쉽지 않다. 그리고 Life Cycle은 어떻게 처리해야 할지 방법조차 묘연한 상황이었다.

 

따라서 딱히 변화가 필요없는 간단한 컴포넌트는 함수형으로 만들 수 있었지만, 위와 같은 불편함 때문에 Class Component를 주력으로 사용할 수 밖에 없었다.

 

React Hooks의 등장

바로 Functional Component에서도 상태 관리, Life Cycle 관리를 할 수 있도록 도와주는 Hooks가 등장한 것이다.

 

Hooks는 컴포넌트가 매번 함수의 호출에 의해 만들어짐에도, 어떤 상태를 유지할 수 있도록 돕는다.

Hooks가 해결한 문제를 React 공식 문서에는 아래와 같이 말하고 있다.

 

- 재사용하기 어려웠던 상태 로직 : 기존에는 상태 로직을 담고 있는 코드를 각 컴포넌트에 바로 붙이는게 불가능했다. 그래서 기존에는 추가적인 계층을 또 만들어서 적용해야 했다. 이렇게 여러 계층을 추가적으로 만들어가면서 구현해야 하는 불편한 점이 있었는데, Hooks는 이걸 한 컴포넌트 안에서 할 수 있도록 도와준다.

- 복잡하고 읽기 어려운 컴포넌트 코드 구조 : Life Cycle을 관리할 수 있게 해주는 componentDidMount, componentDidUpdate 같은 메서드는 한 Class Component에 한 개 존재해야 한다. 그렇다보니 한 컴포넌트가 담당하고 있는 것이 많아지고 커질 수록 위 두 메서드에 들어가는 코드의 양이 많아진다. 이러한 문제점을 해소하기 위해 useEffect Hook이 등장하였다.

 

(출처 : https://medium.com/hcleedev/web-react-hooks%EC%9D%98-%EB%93%B1%EC%9E%A5-%EB%B0%B0%EA%B2%BD%EA%B3%BC-%EC%9D%98%EC%9D%98-d400cbc203a4 )

 

Web: React Hooks의 등장 배경과 의의

React Hooks는 왜 등장했는지, 어떤 의미가 있는지 알아보자

medium.com