ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] HOC(high order component)의 개념과 사용법
    React 2022. 8. 30. 19:57

    오늘은 react의 hoc 패턴에 대해 알아보겠습니다.

     


    1) hoc란?

    hoc는 high order component의 약자로써, 고차컴포넌트라고 합니다.

    쉽게 말하면, 다른 컴포넌트(=자식)를 감싸는 wrapper 컴포넌트(=부모)라는 뜻입니다.

    리액트 공식 문서에 따르면 hoc를 사용하는 이유는 횡단관심사의 분리 입니다.

    횡단관심사는 Cross-Cutting concern이라고 합니다.

    하나의 컴포넌트만 가지고 있는 관심사를 넘어서 여러 컴포넌트에서 가지고 있는 공통의 관심사라는 의미입니다.

     

    예를 들어,

    각 페이지 별 유저에 대한 권한을 검사해 검증을 하는 기능이 공통적으로 가지고 있다고 합시다.

    이러한 권한 검사가 공통의 관심사가 됩니다.

    이러한 페이지 컴포넌트를 자식 컴포넌트로, 검증하는 컴포넌트를 부모컴포넌트로 대입하여 hoc에 적용할 수 있습니다.

     

    즉, 유저를 검증하는 컴포넌트(hoc)는, 각 페이지별 컴포넌트를 렌더링을 할지, redirect 처리를 할지 결정하는 기능을 담당합니다.

    이렇게 공통적인 기능에 대해 hoc를 통해 분리를 함으로써, 컴포넌트 로직을 재사용할 수 있는 장점이 있습니다.

     

     

     

    2) 사용법

    [1] 파일 naming

    일반적으로 자주 사용하는 규칙은, hoc 라는 폴더 아래에 with~~ 형식으로 파일을 생성합니다.

    ex) withRouteGuard

     

    [2] hoc 생성

    import Router from 'next/router';
    import { useEffect, useState, useContext } from 'react';
    
    const withAuth = (WrappedComponent) => {
      const RouteGuard = (props) => {
      
    	 // route guard 처리
     
    	}
      RouteGuard.displayName = `Route guard - (${getDisplayName(WrappedComponent)})`;;
      return RouteGuard;
    };
    
    function getDisplayName(WrappedComponent) {
      return WrappedComponent.displayName || WrappedComponent.name || 'Component';
    }
    
    export default withAuth;

    (+) Tip: 디버깅 처리를 쉽게 하기 위해 displayName에 wrappedComponent의 이름을 전달합니다.

     

    [3] component에 적용

    import withAuth from 'hoc/withRouteGuard';
    
    const Example = () => {
    	// 예시 component  
    }
    
    export default withAuth(Example);

     

     

    3) 주의사항

    [1] 고차 컴포넌트를 사용할 컴포넌트의 render에 선언하지 않는다.

    고차컴포넌트는 한번만 실행되게 만들어져야 한다. 하지만, render()에 고차컴포넌트를 선언한다면, 고차컴포넌트 또한 여러번 렌더링이 될 것입니다.

    그러므로, 바깥에 정의하시면 됩니다.

    [2] 정적메서드는 따로 복사해야 합니다.

    [3] ref는 전달되지 않습니다.

     

     


    참조문서

    https://ko.reactjs.org/docs/higher-order-components.html

Designed by Tistory.