이번 프로젝트의 목표 중 하나는 재사용성이 높은 컴포넌트를 만드는 것이었다. 프로젝트를 진행하며 인증에 관한 로직이 중복되는 것을 발견했고 위 문제를 해결하기 위한 과정을 담은 글이다.
현재 서비스 상, 로그인이 되어 있지 않을 때 접근을 제어해야 하는 컴포넌트가 상당히 많다.
예를 들어, 아래와 같이 사이드 바의 내 투자, 내 관심 컴포넌트와 내 계좌 페이지 등 로그인한 사용자만 접근할 수 있는 컴포넌트 및 페이지들이 다수 존재했으며 위 페이지들에서 중복된 로직들은 다음과 같았다.
function MyAccount() {
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
const { data } = useMyAccount(); // 문제 발생
const balanceMarketList = useMemo(
// 생략
);
const { sseData } = useSSETicker(balanceMarketList);
const formatters = formatData('KRW');
if (!isAuthenticated) return <NotLogin size="sm" />;
return (
// 생략
);
}
export default MyAccount;
초기 개발 단계에서는 로그인 상태 확인 -> 비로그인 시 안내 페이지로 전환
로직들을 각 컴포넌트마다 반복해서 작성했으며 개발 중 위 방식의 문제점들을 발견했다.
function MyAccount() {
const { isLoggedIn, user } = useAuth();
if (!isLoggedIn) {
return <NotLogin size="sm" />;
}
return <div>MyAccount Content</div>;
}
export default MyAccount
초기 해결 과정은 커스텀 훅을 통해 중복 로직을 분리한 후 커스텀 훅 호출을 통해 로그인 인증 여부를 확인하는 방법이었다.
커스텀 훅 방식을 통해 로그인 인증을 확인하는 로직의 중복을 줄일 수 있었지만 2가지의 아쉬운 점이 남았다.
이러한 문제를 해결하기 위해 HOC 패턴을 도입했다. HOC 패턴이란 다음과 같다.
고차 컴포넌트(Higher-Order Component, HOC)는 컴포넌트를 매개변수로 받아서 새로운 컴포넌트를 반환하는 함수로, 컴포넌트 로직을 재사용하기 위한 React 의 패턴 중 하나이다.
function withAuthenticate<P extends object>({
WrappedComponent,
}: WithAuthProps<P>) {
return function AuthenticatedComponent(props: P) {
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
if (!isAuthenticated) return <NotLogin />;
return <WrappedComponent {...props} />;
};
}
export default withAuthenticate;
withAuthenticate
함수는 우리가 인증을 확인하고 싶은 컴포넌트(WrappedComponent
)를 인자로 받는다.AuthenticatedComponent
)를 반환한다.AuthenticatedComponent
는 실제 인증 로직을 수행한다NotLogin
컴포넌트를 반환한다.WrappedComponent
를 렌더링한다.function MyAccount(){
// 내 계좌와 관련된 로직
}
export default withAuthenticate(MyAccount);
위와 같이 인증이 필요한 페이지는 아래와 같이 간단하게 처리할 수 있게 되었으며 HOC 패턴 도입으로 각 페이지 컴포넌트들은 비즈니스 로직에만 집중할 수 있게 됐다.
HOC 패턴 도입으로 다음과 같은 이점을 얻을 수 있었다
1. 관심사의 명확한 분리
2. 선언적 프로그래밍
3. 재사용성
위와 같은 고민 과정을 거쳐 HOC 패턴을 선택했고, 결과적으로 더 깔끔하고 유지보수하기 좋은 코드를 작성할 수 있었다. 물론 커스텀 훅 방식이 나쁜 방식은 전혀 아니지만 아쉬움을 해결하기 위해 HOC 패턴을 학습하고 직접 적용해보며 재사용성 높은 컴포넌트를 위한 다양한 접근 방식을 학습할 수 있었던 좋은 기회가 되었다.