HOC(Higher Order Component)

오준상·2020년 11월 21일
0
post-thumbnail
post-custom-banner

HOC

내가 이 HOC에 대해서 알게 된 이유는, 단지 코드의 중복을 줄일 수 없을까? 라고 생각하던 도중에
동기 중 1명이 이것에 대해 알려 주었는데, 비슷한 동작이 여러번 반복되는 컴포넌트가 있을 때, 다른 함수로 여러번 빼지 않고 한개의 컴포넌트로 묶을 수 있게 되므로, 효율적이라고 생각하였습니다. 그래서 정리하게 되었습니다.

what is HOC

우선 시작하기 전에 React Docs에 있는 HOC에 대한 설명을 알려 드리겠습니다.

고차 컴포넌트 (HOC, higher-order component)는 컴포넌트 로직재사용하기 위한 React의 고급 기술입니다.

제가 생각하는 HOC도 비슷합니다. 중복되는 코드재사용 하기 위해서 component로 빼내는 것.
이것이 제가 생각하는 HOC 입니다.

why use HOC

그래서 HOC는 왜 사용하는가? 사실 무엇인지 설명하는 대에 목적이 나와서 딱히 설명할 것은 없는데요.
개인적인 사용 사례를 알려 드리겠습니다. 저는 이 HOC를 사용자 토큰 체크 request를 할때 사용하였습니다.
어떤 서비스던지 어드민 페이지의 경우, 일반 유저는 접근할 수 없어야 합니다. 그래서 어떤 특정한 api에 유저가 기자고 있는 access token을 보내서 일반 유저 인지 어드민 인지 판단 후, 웹사이트를 보여주는 것이 맞다고 생각합니다. 그 때, 이 request 를 보내는 HOC를 만든 후, Admin Router에 묶어서 실행 해보니 완벽하게 작동하던 경험이 있습니다.

예시 코드

import React, { useCallback, useEffect } from 'react';
import { getUserAuth } from '../../lib/api/Admin';
import { useHistory } from 'react-router-dom';

const WithCheckAdmin = () => Component => {
  const HOC = () => {
    const history = useHistory();
    const errorHandler = ({ response: { data } }) => {
      if (data.status === 403) {
        history.push('/admin/login');
      }
    };
    getUserAuth().catch(error => { // 어드민인지 확인하는 server request
      errorHandler(error); // 아니면 status code 403으로 error 발생.
    });
    return <Component />; // 매개변수로 받은 Component Return
  };
  return HOC; // 매개변수로 받은 Component를 return 하는 함수를 return하는  Component를 return
};

export default WithCheckAdmin;

다음은 HOC 코드이다. 블로그 서비스 운영자님께서 쓰신 글을 읽었을 때, HOC의 이름은 with로 사용하는게 대부분이라고 하셔서 그렇게 해보았다.

사용법은 다음과 같다

import React, { useState } from 'react';
import { Switch, Route } from 'react-router-dom';
import AdminNavigation from '../Default/AdminNavigation';
import { AdminPost, AdminUserDetail } from '../';
import { WithCheckAdmin } from '../HOC';

const AdminRouter = () => {
  const [selectedContentId, selectedContentIdChange] = useState('user');
  return (
    <>
      <AdminNavigation selectedContentId={selectedContentId} />
      <Switch>
        <Route
          path="/admin/user/:userId"
          render={() => (
            <AdminUserDetail
              selectedContentIdChange={selectedContentIdChange}
            />
          )}
        />
        <Route
          exact
          path="/admin"
          render={() => (
            <AdminPost selectedContentIdChange={selectedContentIdChange} />
          )}
        />
      </Switch>
    </>
  );
};

export default WithCheckAdmin()(AdminRouter); // admin page routing 부분
//에서 HOC로 묶어서 export 해주기 때문에 모든 admin page에서 user auth check 실행

결론

중복되는 component나 코드를 HOC라는 컴포넌트로 묶어서 처리할 수 있다.

profile
만들고싶은걸만듭니다
post-custom-banner

0개의 댓글