새로운 블로그로 이전 작업을 진행하고 있어 포스트가 새로 작성되고 있지 않습니다.

빠른 시일 내에 새로운 블로그로 인사드리겠습니다.

새로운 블로그 : https://unho.vercel.app/

본문 바로가기
공부 및 정리/프론트엔드

[React] 클래스형과 함수형 컴포넌트

by 언호 2021. 12. 29.

개인 학습 과정에서 작성한 markdown 문서로 잘못된 내용이 존재할 수 있습니다

잘못된 내용 또는 개선 방안을 말씀해주시면 수정하겠습니다.

 

 

 

📝 클래스형과 함수형 컴포넌트

공식문서와 유튜브 영상들을 참고해서 공부하던 중 컴포넌트를 사용하는 방식이 클래스형과 함수형 두가지가 존재하는것을 알게 되었다.

이 두가지 방식을 보고 어떤게 더 좋고 미래에 자주 사용할지 등과 같은 여러 사항들이 궁금해져 조금 더 공부해보려 한다.

두개 중 어느것이 좋고 승자를 가리기보다 두가지를 비교하고 차이점을 알고자한다.

 

 

1. 과거와 현재

과거

다수의 사람들은 과거에 함수형 보다는 클래스형 컴포넌트를 주로 사용해왔다.

과거에 클래스형을 많이 사용했던 대표적인 이유로는 state와 컴포넌트 LifeCycle을 사용할 수 있었기 때문에 클래스형 컴포넌트를 많이 사용하였다.

반면에 함수형은 state 와 LifeCycle을 사용할 수 없어 개발 과정에 어려움이 생겨 클래스를 더 자주 사용하였다고 한다.

 

현재

그러나 리액트에서 16.8 버전 이후로 'Hook' 이 도입 되면서 함수형 컴포넌트도 state와 LifeCycle 을 사용할 수 있게 되면서 단점을 보완하게 되었다.

훅을 사용할 수 있게된 이후로 함수형은 오히려 클래스형 컴포넌트 보다 조금 더 편해진 방법으로 사용할 수 있게 되었다.

 

나의 근본적인 궁금증은 "클래스형 컴포넌트는 학습하지 말고 함수형 컴포넌트만 학습해야 할까??" 였다.

 

클래스형과 함수형 모두 이해하고 사용할 수 있어야 한다

 

리액트 공식문서를 참고하면 함수형 컴포넌트의 단점을 보완하기 위해서 훅을 만들었지만, 클래스형 컴포넌트를 없애기 위해서 만들어낸것은 아니라고 한다. 또한, 현재까지 만들어진 클래스형을 모두 함수형으로 바꿀 필요가 없다.

 

많은 기업들이 이전에 클래스형으로 개발을 해왔기에 그 내용을 이해하고 추가로 개발을 위해서는 필수적으로 클래스형에 대한 이해가 필요하다.

개발하는 팀에서 훅이나 함수형을 사용하기 어려워한다면 클래스형으로 개발을 해야하기 때문에 학습이 필요하다.

다만, 함수형과 클래스형은 구조가 조금 차이가 있는데 이때 발생하는 버그를 방지하기 위해서 앞으로 함수형 컴포넌트를 사용하는것이 더 좋다.

 

 

2. 실행 구조 비교

해당 주제의 내용은 본 문서 가장 하단에 작성한 참고 자료 블로그-1 의 내용을 참고하여 학습 및 정리했습니다.
조금 더 자세한 사항은 해당 블로그를 읽으시면 도움이 될 수 있습니다.

 

두가지 컴포넌트의 구조를 비교하기 위해 코드를 살펴보자.

클래스형 컴포넌트

class ClassComponent extends React.Component {
  alertPopup() {
    alert('alert' + this.props.data);
  };

  clicked() {
    setTimeout(this.alertPopup, 1000);
  };

  render() {
    return <button onClick={this.clicked}>알람</button>;
  }
}

클래스형 컴포넌트의 특징으로 부모 컴포넌트로부터 전달받은 props 를 사용하기 위해서는 this 를 사용해 this.props.data 로 사용해야한다.

 

함수형 컴포넌트

function FunctionComponent(props) {
  function alertPopup() {
    alert('alert' + props.data);
  };

  function clicked() {
    setTimeout(alertPopup, 1000);
  };

  return <button onClick={clicked}>알람</button>;
}

함수형 컴포넌트에서는 props 를 사용하기 위해서는 단순히 props.data 로 사용하면 된다.

 

차이점

위의 두가지 코드의 로직은 단순하다.

버튼을 클릭하면 clicked 함수가 실행이 되고, 1초 뒤에 alertPopup 함수가 실행이 되면서 현재 props에 있는 data의 값을 알림창으로 띄운다.

 

하나의 페이지에서 저 코드를 실행하면 문제가 없을것이다.

그러나 알림창이 뜨기 이전에 페이지 이동과 같은 일을 수행해서 컴포넌트를 새로운 값으로 렌더링 하는 경우에 문제가 생긴다.

이해를 위해 두가지를 나누어 이해해보자

 

클래스형

  1. 버튼 클릭
  2. clicked 함수 실행으로 alertPopup을 1초뒤 실행되도록 함
  3. 알림이 뜨기 이전에 페이지 이동과 같은 행동이 이루어짐 (상위 컴포넌트에서 props의 값이 다른 값으로 컴포넌트를 렌더링 시킴)
  4. 1초가 지난 후 alertPopup 함수가 실행됨
  5. 알림창에 this.props.data가 실행됨

props 는 불변(immutable) 값인데, this는 변경 가능한(mutable) 값이다.

그로 인해서 버튼을 눌렀을때의 데이터를 띄워야 하는데, 다른 페이지 이동(부모 컴포넌트가 다른 props로 렌더링 시킴)과 같은 일이 생겼다.

그래서 this 가 가리키고 있는 객체가 새로운 객체로 변하게 되고, alertPopup 함수는 새로운 객체가 갖고 있는 props 의 데이터를 출력하게 된다.

 

함수형

  1. 버튼 클릭
  2. clicked 함수 실행으로 alertPopup을 1초뒤 실행되도록 함
  3. 알림이 뜨기 이전에 페이지 이동과 같은 행동이 이루어짐
  4. 1초가 지난 후 alertPopup 함수가 실행됨
  5. 알림창에 props.data가 실행됨

props 는 기본적으로 불변(immutable)한 성질을 가지고 있기 때문에, 클래스형과 다르게 중간에 다른 페이지로 이동과 같은 행동을 하더라도 함수형 컴포넌트가 가지고 있던 props 의 값이 변하지 않고 그대로 출력하게 된다.

 

이와 같은 차이로 클래스형은 원치 않는 값을 나타내 버그가 발생하게 된다.

이런 버그를 막기 위해 몇가지 방법(변수에 저장, 클로져 등)을 사용할 수 있지만, 코드가 길어지고 내용이 많아진다면 관리에 어려움이 생기게 된다.

 

 

3. 컴포넌트 LifeCycle

학습을 하던 중 클래스형에서 LifeCycle을 사용할때 어떤게 있는지 궁금했었다.

공식 문서상 LifeCycle 내용은 텍스트로 이루어져 있어서 구글을 통해 이미지를 구했다.

구글에 검색하면 보이는 가장 대표적인 이미지 중 하나인데, 함수들의 이름도 길고 순서가 생각보다 복잡하다.

나는 처음에 Vue를 학습했는데, Vue 의 LifeCycle 이 조금 더 직관적이고 순서를 이해하기 쉬웠다.

 

이전에 함수형에서는 LifeCycle 을 사용할 수 없어, 클래스형에서 저러한 LifeCycle 을 이용했는데 생각보다 문제가 많았다고 한다.

예를 들면, 중복된 코드를 여러 LifeCycle에서 동작시켜야 하거나 특정 LifeCycle 의 순서를 잘못 인지해 코드를 잘못 작성하거나 등등.. 관리의 어려움이 있었다고 한다.

 

그러나 훅이 나와서 함수형 컴포넌트에서도 LifeCycle을 사용할 수 있게된 지금은 조금 더 간편한 방법으로 사용이 가능하다.

공식 문서를 참고하면 useEffect 를 이용하면 'componentDidMount' , 'componentDidUpdate', 'componentWillUnmount' 가 합쳐진 것처럼 동작할 수 있게 된다.

 

훅 덕분에 함수형에서도 LifeCycle을 사용할 수 있게 되었다.

 

 

 

참고 자료

- 공식 문서
- 블로그-1

- 블로그-2

 

댓글