Functional Component

landvibe
5 min readJul 2, 2017

--

2018–12–01 리액트 버전 16.7부터는 함수형 컴포넌트에서도 상태값과 생명 주기 함수를 이용할 수 있다.

react에는 두 가지 종류의 컴포넌트가 있다. 하나는 클래스로 만들어진 class component이고 다른 하나는 함수로 만들어진 functional component이다.

// class component
class Player extends React.Component {
render() {
return <div>
<p>{this.props.name}</p>
<p>{this.props.age}</p>
</div>
}
}
// functional component
function Player(props) {
return <div>
<p>{props.name}</p>
<p>{props.age}</p>
</div>
}

둘 사이에는 분명한 차이점이 있기 때문에 각각의 장단점을 잘 이해하고 사용해야 한다. 기능적인 측면에서 보자면 class component는 functional component가 할 수 있는 모든 일을 할 수 있다. functional component가 할 수 없는 일은 다음과 같다

  • state를 가질 수 없다
  • lifecycle 함수를 작성할 수 없다

functional component의 장점은 부족한 기능에서 나온다. state가 없기 때문에 보다 더 이해하기 쉬운 코드를 작성할 수 있다. 프로그래밍에서 수정 가능한 변수는 코드를 복잡하게 만드는 주범이다.

lifecycle 함수가 필요 없기 때문에 효율적인 렌더링이 가능해진다. class component는 각 렌더링 단계마다 lifecycle 함수가 호출되기 때문에 functional component에 비해 추가적인 연산이 더 필요하다. 또한 lifecycle 함수가 동작하려면 prevProps, prevState값을 메모리에 유지해야 하는데 functional component에서는 그러지 않아도 된다.

따라서 state와 lifecycle 함수가 필요 없다면 functional component를 사용하는 게 일반적으로 더 나은 선택이다.

이 번에는 functional component의 단점을 알아보자.

  • 단점 1. shouldComponentUpdate 함수를 작성할 수 없다.
  • 단점 2. custom event handler를 작성하기가 힘들다.

단점 1은 lifecycle 함수를 작성할 수 없기 때문에 너무나 당연한 사실이다. 컴포넌트 내부에서 렌더링 하는 UI 요소가 복잡한 경우에는 이게 큰 단점이 된다. props가 변하지 않았는데도 렌더링 할 때마다 virtual dom을 생성하기 때문에 불필요한 연산이 발생한다. class component의 경우에는 PureComponent를 통해서 shallow compare를 할 수 있기 때문에 virtual dom 생성을 피할 수 있다.

한 가지 해결책은 recompose의 pure 함수 같은 외부 라이브러리의 도움을 받아야 한다. 단, recompose의 pure 함수를 사용하면 functional component라서 얻을 수 있었던 렌더링 측면에서의 이득은 포기해야 한다. 하지만 UI 요소가 복잡한 경우라면 shallow compare를 통해서 얻는 이득이 더 크다고 할 수 있다.

단점 2는 개인적으로 많이 아쉬운 부분이다.

function Buttons(props) {
function onClick(event) {
props.onClick(event.target.dataset.id);
}
return <div>
<button data-id='cancel' onClick={onClick}>cancel</button>
<button data-id='ok' onClick={onClick}>ok</button>
</div>
}

위 예에서 Buttons 컴포넌트는 렌더링 될 때마다 새로운 onClick 함수를 만든다. 따라서 렌더링 할 때마다 자식 컴포넌트에 변경된 props를 전달하게 되고 비효율적인 렌더링을 초래한다.

아직까지 functional component에서 custom event handler를 작성하는 좋은 방법을 못 찾았기 때문에 그런 경우에는 눈물을 머금고 class component로 변경하고 있다ㅜㅜ

정리하자면 아래의 경우에는 functional component를 사용하자

  • state가 필요 없다
  • lifecycle 함수가 필요 없다
  • custom event handler가 필요 없다

그리고 UI 요소가 많은 functional component는 recompose의 pure 함수 같은 외부 라이브러리의 도움을 받자.

참고 1. 아직까지는 react 엔진에서 functional component의 성능 최적화가 미흡한 수준이다. 다음 major 업데이트인 v16에서 신경써서 최적화를 한다고 하니 기대해보자.

참고 2. redux를 만든 사람으로 유명한 Dan Abramov의 포스팅은 많은 생각할 거리를 안겨준다.

--

--

No responses yet