본문 바로가기

React/React 공부하기

함수형 컴포넌트와 클래스형 컴포넌트의 차이

React 컴포넌트를 만들때 클래스형 컴포넌트, 함수형 컴포넌트 2가지 방식이 있다 

과거에는 클래스형 컴포넌트를 많이 사용했지만

2019년 v16.8 부터 함수형 컴포넌트에 리액트 훅(hook)을 지원해 주어서 

현재는 공식 문서에서도 함수형 컴포넌트와 훅(hook)을 함께 사용할 것을 권장하고 있다. 

 

[함수형 컴포넌트를 선호하는 이유]

요즘은 많은 개발자들이 클래스형 컴포넌트보다 함수형 컴포넌트+Hook을 사용한다.

클래스형 컴포넌트는 로직과 상태를 컴포넌트 내에서 구현하기 때문에 상대적으로 복잡한 UI 로직을 갖고 있는 반면,

함수형 컴포넌트는 state를 사용하지 않고 단순하게 데이터를 받아서(props) UI에 뿌려준다. Hook들을 필요한 곳에 사용하며 Logic의 재사용이 가능하다는 장점이 있어 함수형 컴포넌트+Hook을 주로 사용한다고 한다.

 

먼저 컴포넌트의 기능을 한 번 짚어보고 가도록 하자. 컴포넌트는 단순한 템플릿 이상의 기능을 수행한다. 데이터가 주어졌을 때 이에 맞추어 UI를 만들어 주는 기능을 하는 것은 물론, 라이프 사이클 API를 통해 컴포넌트가 화면에 나타날 때, 사라질 때, 변할 때 작업들을 수행할 수도 있다. 

컴포넌트의 목적에 따라 프리젠테이션(presentational) 컴포넌트컨테이너(container) 컴포넌트로 나누기도 한다.

프레젠테이셔널 컴포넌트

  • View 만을 담당하는 컴포넌트이다 (UI를 작성한다)
  • 이 컴포넌트 안에서는 프레젠테이셔널 컴포넌트와 컨테이너 컴포넌트 둘 다 사용할 수 있다
  • 리덕스 스토어에 직접적으로 접근하지 않고 props로만 데이터, 함수를 가져온다
  • 순수한 컴포넌트로 state를 사용하지 않으며 state가 있을 경우 데이터가 아닌 UI에 대한 state여야 한다.
  • 주로 함수형 컴포넌트로 작성된다

컨테이너 컴포넌트

  • 다른 프레젠테이션 컴포넌트나 컨테이너 컴포넌트를 관리한다
  • 내부에 DOM 엘레멘트를 (UI) 작성하지 않는다 (사용하는 경우 감싸는 용도)
  • 스타일을 가지고 있지 않는다
  • 스타일은 모두 프레젠테이셔널 컴포넌트 내부에 정의되어야 한다
  • 상태를 가지고 있고 리덕스에 직접 접근하여 데이터를 가져온다
  • dispatch를 하는 함수를 여기서 구현한다

 

[ 차이1: 선언방식 ]

클래스형 컴포넌트와 함수형 컴포넌트의 역할은 동일하다. 

 

 

클래스형 컴포넌트

<클래스형 컴포넌트>

1. class 키워드 필요

2. Component로 상속을 받아야한다.

3. render() 메소드가 반드시 필요하다.

4. state, lifeCycle 관련 기능사용이 가능하다.

5. 함수형보다 메모리 자원을 더 사용한다.

6. 임의 메소드를 정의할 수 있다.

 

 

함수형 컴포넌트

 

<함수형 컴포넌트>

 

1. state, lifeCycle 관련 기능사용 불가능하다. [Hook을 통해 해결]

2. 클래스형보다 메모지 자원을 덜 사용한다.

3. 컴포넌트 선언이 편하다.

 

 

 

※ es6 화살표 함수와 일반 function() 함수의 차이 :

일반 함수(function())는 자신이 종속된 객체를 this로 가리키며, 화살표 함수(() => {})는 자신이 종속된 인스턴스를 가리킨다.

( devowen.com/298 예시 참고)


[차이2 : state]

State 란?

컴포넌트 내부에서 바뀔 수 있는 값

 

<클래스형 컴포넌트>

1. constructor 안에서 this.state 초기 값 설정 가능

2. counstructor 없이도 바로 state 초기값을 설정 가능

3. this.setState() 를 통해 state값을 변경

4. 클래스형의 state는 객체형식

 

 

 

 

 

 

 

 

 

 

 

 

 

<함수형 컴포넌트>

1. useState 함수로 state를 사용한다.

2. useState 함수를 호출하면 배열이 반환되는데 첫 번째 원소는 현재 상태, 두번째 원소는 상태를 바꿔주는 함수이다.

 

 

 

 

 

 

 

 

 

[차이3 : props ]

Props 란?

- 컴포넌트의 속성을 설정

- 읽기 전용 (컴포넌트 자체 props를 수정하면 안된다.)

- 모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수처럼 동작해야한다.

- 수정되는 값은 state 이다.

 

<클래스형 컴포넌트>

1. this.props로 통해 값을 불러올 수 있다.

 

 

 

 

 

 

 

<함수형 컴포넌트>

1. props를 불러올 필요 없이 바로 호출 할 수 있다.

 

 

 

 

 

 

 

 

 

 

[차이4 : 이벤트 핸들링]

 

<클래스형 컴포넌트>

1. 함수 선언시 화살표 함수로 바로 선언 가능하다.

2. 요소에 적용할때 this.를 붙여줘야한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<함수형 컴포넌트>

1. const + 함수 형태로 선언해야 한다.

2. 요소에 적용할때 this가 필요없다.

 

 

 

 

 

 

 

 

 

 

[차이5 : Life Cycle]

Life Cycle 이란?

- React에서 컴포넌트는 여러 종류의 "생명주기 메소드" 를 가지며 이 메소드를 오버라이딩(상속하여 재정의) 하여 특정 시점에 코드가 실행되도록 설정 합니다.

- 클래스 컴포넌트에만 해당되는 내용이며, 함수형 컴포넌트는 Hook를 사용하여 생명주기에 원하는 동작을 합니다

<클래스형 컴포넌트>

Life Cycle

위의 과정을 설명하자면

 

- Mounting (생성 될 때) -

: 컴포넌트가 인스턴스로 생성되고 DOM 트리에 삽입되어 브라우저상에 나타나는 과정

 

  • constructor

시점 :

브라우저상에 나타날때 가장 처음 실행되는 함수

사용이유 :

생성자 메서드로 this.state의 초기값 설정, 인스턴스에 이벤트 처리 메서드를 바인딩하기 위해 사용한다.

super(props)를 첫 줄에 필수로 사용한다.

ex) constuctor

  • static getDerivedStateFromProps

시점 :

컴포넌트가 처음 렌더링 되기 전에도 호출 되고 그 이후 리렌더링 되기 전에도 매번 실행됩니다

사용이유 :

props로 받은 값을 state에다가 넣고 싶을때 사용 (거의 쓰지 않는 함수라고 합니다.)

 

ex) getDerivedStateFromProps

  • render() : 컴포넌트를 렌더링하는 메서드입니다.

ex) render

  • componentDidMount

시점 :

컴포넌트가 생성된 직후, 트리에 삽입된 직후에 호출됩니다 이 메서드가 호출되는 시점에는 우리가 만든 컴포넌트가 화면에 나타난 상태입니다

사용이유 : 

외부 라이브러리를 사용하여 특정 DOM에다가 차트를 그릴때,

컴포넌트에서 필요로하는 데이터 요청, DOM의 속성을 읽거나 직접 변경하는 작업을 할 때 등

 

- Updating (업데이트 할 때) -

: 컴포넌트 props 또는 state가 바뀌었을 때

 

  • static getDerivedStateFromProps

: Mounting 에서 등장한 메서드로 업데이트에서도 호출됩니다.

 

 

  • shouldComponentUpdate

시점 : 

props 또는 state가 새로운 값으로 갱신되어 렌더링이 발생하기 직전에 호출

사용이유 :

성능최적화를 위해 사용한다. 컴포넌트가 리렌더링을 할지 말지 결정하는 메소드이다.

(함수형 컴포넌트에선 useMemo()가 같은 역할을 한다.)

리액트 공식 홈페이지에서는 이 메소드 대신 PureComponent를 사용하는 것이 좋다고 한다.

ex) shouldComponentUpdate

  • render

: Mounting 에서 등장한 메서드로 업데이트에서도 호출됩니다.

 

  • getSnapshotBeforeUpdate

시점 :

render 메서드 호출 후 브라우저에 나타나기 바로 직전에 호출되는 메서드이다.

(render() -> getSnapshotBeforeUpdate -> DOM에 변화 반영 -> componentDidUpdate)

사용이유 :

브라우저에 그리기 전에 스크롤의 위치, DOM의 크기를 사전에 알고 싶을 때,

업데이트 되기 직전에 DOM 함수를 return 시켜가지고 그 return된 값을 componentDidUpdate에서 받을 수 있다

 

이 메소드는 사용할 일이 별로 없지만 Hook에서 대체할 수 있는 기능이 아직 없다고 합니다.

예제) codesandbox.io/s/484zvr87ow?file=/src/index.js 참고

 

  • componentDidUpdate

시점 : 

리렌더링을 완료한 후 실행되는 메서드이다. 화면에 우리가 원하는 변화가 모두 반영되고 난 뒤 호출

사용이유 : 

컴포넌트가 업데이트 되었을 시에 DOM을 조작하기 위해 사용하거나

이전과 현재의 props를 비교하여 네트워크 요청을 보내는 작업을 할 때 유용

 

- Unmounting (제거 할 때) -

: 컴포넌트가 브라우저상에서 사라질때

 

  • componentWillUnmount

시점 : 

컴포넌트가 브라우저상에서 사라질때

사용이유 : 

주로 DOM에 직접 등록했었던 이벤트를 제거하거나

setTimeout이 있다면 타이머를 제거, 외부 라이브러리 인스턴스를 제거하기 위해 사용

 

- 컴포넌트 에러가 발생했을때 -

  • componentDidCatch

시점 :

render 함수에서 에러가 날 때, 에러가 발생할 수 있는 컴포넌트의 부모 컴포넌트에서 작업해야한다.

사용이유 : 

사용자에게는 에러 화면을 보여주고 , 개발자들은 이때 에러 내용을 서버로 전달할 때 사용합니다.

ex) componentDidCatch

<함수형 컴포넌트>

Hook 게시물 참고

 

[참고]

velog.io/@ksmself/useState-useEffect

devowen.com/298

kyung-a.tistory.com/21

[프레젠테이션,컨테이너 컴포넌트 개념 참고]

haerang94.tistory.com/110

 

 

 

'React > React 공부하기' 카테고리의 다른 글

컴포넌트 반복 : map()  (0) 2021.04.26
ref: DOM  (0) 2021.04.26