React의 HoC 정리하기

1 minute read

하이어오더 컴포넌트란?

하이어오더 컴포넌트를 한마디로 정의하면 기존 컴포넌트에 기능을 덧입혀 새 컴포넌트로 반환하는 함수를 말한다.
이전 포스팅에서 커링을 다루었다. 커링 포스팅보러가기
형태는 커링하고 똑같다고 보면 된다.

//함수형 컴포넌트를 반환
function HoFC(Component){
    return function Enhanced(props){
        return <Component {...props} />
    }
}

//클래스형 컴포넌트를 반환
function HoCC(Component){
    return class Enhanced extends React.Component {
        render(){
            return <Component {...this.props}>
        }
    }
}

위의 형태 같이 컴포넌트를 받아서 기존의 컴포넌트에 기능이 향상된 컴포넌트를 반환한다!

데코레이터 패턴

위의 HoC에서 사용하는 것이 데코레이터 패턴이다. 클래스 간의 종속성 없이(상속 없이) 기능만을 공유하는 것을 데코레이터 패턴이라고 한다.
왜 상속을 사용하지 않냐면 종속성이 계속 생기다보면(상속을 계속 하다보면) 중간에 컴포넌트가 원치 않는 상속을 받아야 할 수도 있다. 즉 필요없는 기능이 컴포넌트에 추가되는 것이다.
또한 상속 구조가 깊어지면 상속의 항목을 한번에 파악하기가 어려워서 코드의 수정이 더 어려워지게 된다. 그래서 데코레이더 패턴을 쓰는 것이다.

하이어오더 컴포넌트를 만들 때 주의할 점

  1. 기존 컴포넌트에 연결된 props를 모두 전달해 주어야 한다.
  2. HoC와 확장 컴포넌트의 이름은 with로 시작한다.

1번을 보자면 위의 예시에서 {…props}와 {…this.props}로 기존의 프로퍼티들을 전달하고 있는 것을 알 수 있다. 그리고 만약에 전달하지 않아도 되는 prop는 따로 값을 받아서 전달하지 않도록 만들어도 된다.
2번의 경우엔 HoC함수의 이름이 withError이라면 만들어진 컴포넌트는 ButtonWithError 이라고 생각하면 된다. 강제적인것은 아니지만 암묵적으로 with를 붙인다.

로딩 예제를 통해서 알아보기

export default function(loadingMessage = '로딩 중'){
    return function withLoading(WrappedComponent){
        function WithLoading({isLoading, ...otherProps}){ // 주의
            if(isLoading) return loadingMessage;
            return (
                <WrappedComponent {...otherProps}>
            )
        }
        return WithLoading;
    }
}

사용방법은 맨처음 인수로는 로딩 메세지를 전달해주고 그다음은 컴포넌트를 전달해주면 된다.

(...)
import withLoading from "위의 함수";
import Component from "기존 컴포넌트";

const ComponentWithLoading = withLoading('로딩 중입니다.')(Component);

// 컴포넌트 사용할 때
<ComponentWithLoading isLoading>컴포넌트 렌더링</ComponentWithLoading>

isLoading을 전달하면 props.isLoading이 true가 되기때문에 맨처음 입력했던 로딩 메시지가 나온다.
isLoading과 …otherProps 부분을 보자. isLoading은 WrappedComponent에 전달할 필요가 없다. (예제에서는 Component)
그래서 구조할당을 통해서 그 부분만 따로 받아서 전달하지 않고, otherProps를 통해서 나머지 프로퍼티만 전달한 것이다.

Leave a comment