내가 이 HOC에 대해서 알게 된 이유는, 단지 코드의 중복을 줄일 수 없을까?
라고 생각하던 도중에
동기 중 1명이 이것에 대해 알려 주었는데, 비슷한 동작이 여러번 반복되는 컴포넌트
가 있을 때, 다른 함수로 여러번 빼지 않고 한개의 컴포넌트로 묶을 수 있게 되므로, 효율적이라고 생각하였습니다. 그래서 정리하게 되었습니다.
우선 시작하기 전에 React Docs에 있는 HOC에 대한 설명을 알려 드리겠습니다.
고차 컴포넌트 (HOC, higher-order component)는
컴포넌트 로직
을재사용
하기 위한 React의 고급 기술입니다.
제가 생각하는 HOC도 비슷합니다. 중복되는 코드
를 재사용
하기 위해서 component
로 빼내는 것.
이것이 제가 생각하는 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라는 컴포넌트로 묶어서 처리할 수 있다.