고차 컴포넌트(HOC)

NoName·2021년 10월 14일
0

고차컴포넌트란?

고차 컴포넌트는 컴포넌트를 가져와 새 컴포넌트를 반환하는 함수입니다.

고차 컴포넌트(HOC, Higher Order Component)는 컴포넌트 로직을 재사용하기 위한 React의 고급 기술입니다. 고차 컴포넌트(HOC)는 React API의 일부가 아니며, 리액트의 구성적 특성에서 나오는 패턴입니다.

고차 컴포넌트가 쓰이는 이유는?

공식문서에서는 횡단 관심사(Cross-Cutting Concerns) 문제를 해결하는 데 쓰인다고 언급합니다.

횡단 관심사(Cross-Cutting Concerns)란?

비즈니스 로직과 구분되는 공통 기능(ex. 로깅, 로딩, 보안, 트랜잭션 등)

고차 컴포넌트(HOC) vs 훅(Hooks)

공식 문서에서는 대부분의 경우 Hooks로 대체 가능하다고 말합니다.

클래스 컴포넌트로만 개발해야 했을 때, 주로 고차 컴포넌트는 생명주기에 종속적이지 않으면서 중복된 코드를 분리하기 위해서 사용했습니다. 그러다보니 HOC가 반환하는 중복되는 컴포넌트 레이어들이 쌓이는 문제가 발생했습니다.

하지만 Hooks가 릴리즈되면서 생명주기가 단순화 되었고, 공통의 코드 분리가 필요한 경우에는 custom hook을 사용하면 해결 할 수 있게 되었습니다. custom hooks를 사용하면 컴포넌트가 중첩 되지 않아서 hoc에서 발생했던 문제를 해결 할 수 있습니다.

더 구체적으로 정리해보자면,

고차 컴포넌트를 사용하기 부적합한 경우

  • 컴포넌트에 여러 가지 기능을 추가해야 합니다.
  • 오로지 한 개의 컴포넌트에서만 사용됩니다.
  • 각 컴포넌트에 맞게 커스터마이징해야 합니다.

고차 컴포넌트를 사용하기 적합한 경우

  • 동작은 특정 컴포넌트에 한정되지 않고 앱의 많은 컴포넌트 또는 모든 컴포넌트에 적용되며,
    해당 동작을 사용하는 컴포넌트에 여러 가지 기능을 제공할 필요가 없습니다.
  • 고차 컴포넌트 없이 독립적으로 사용할 수 있는 컴포넌트인 경우.
  • 고차 컴포넌트로 포장되는 컴포넌트에 사용자 지정 로직을 추가할 필요가 없습니다.

공식문서 참고
medium 참고

예제

아래는 logger API에 모든 페이지 뷰를 기록하는 예제입니다.

import React, { useEffect } from 'react';
const withLogging = Component => props => {
  useEffect(() => {
    fetch(`/logger?location=${ window.location}`);
  }, []);
  return <Component {...props } />;
};
export default withLogging;

고차 컴포넌트를 조합하여 아래와 같이 사용할 수 있습니다.

import compose from 'ramda';
import withRedux from './with-redux.js';
import withAuth from './with-auth.js';
import withLogging from './with-logging.js';
import withLayout from './with-layout.js';
const page = compose(
  withRedux,
  withAuth,
  withLogging,
  withLayout('default'),
);
export default page;

위와 같이 사용했을 경우 컴포넌트 계층 구조는 아래와 같습니다.

<withRedux>
  <withAuth>
    <withLogging>
      <withLayout>
        <MyPageComponent />
      </withLayout>
    </withLogging>
  </withAuth>
</withRedux>

실제로 아래와 같이 적용할 수 있습니다.

import page from '../hocs/page.js';
import MyPageComponent from './my-page-component.js';
export default page(MyPageComponent);
profile
I don't know js

0개의 댓글