recompose 의 fromRenderProps 사용해서 HOC 더 쉽게 쓰기

Context API 를 사용 할 때, Consumer 컴포넌트를 Render Props 와 함께 사용하는 것을 편하게 여기는 사람들도 있고, HOC 화 해서 사용하는 것을 편하게 여기는 사람들도 있을 것입니다.

저는 개인적으로 리덕스의 connect 함수를 꾸준히 사용해왔어서 왠지 HOC 가 아직은 적응이 되어있습니다.

만약에 Context API 를 HOC 로 쓰고 싶다면 새로운 Context 를 만들때마다

function useAnother(WrappedComponent) {
  return function UseAnother(props) {
    return (
      <AnotherConsumer>
        {
          ({ state, actions }) => (
            <WrappedComponent
              number={state.number}
              increment={actions.increment}
            />
          )
        }
      </AnotherConsumer>
    )
  }
}

이런식으로 또 따로 함수를 만들어줘야하는데, 조금은 귀찮을수도 있습니다. 일단, 이 작업이 어찌보면 반복되는 작업이기도 합니다. 이를 편하게 처리하기 위해서 useAnother 같은 함수를 만들어주는 함수를 작성하는것도 방법이지만 (참고), recompose 라이브러리에 fromRenderProps 라는 훌륭한 함수가 이미 존재하기에, 한번 이를 사용하여 구현을 해보겠습니다.

우선 설치를 해주시구요,

$ yarn add recompose

fromRenderProps 는 이렇게 사용합니다:

fromRenderProps(
  RenderPropsComponent: ReactClass | ReactFunctionalComponent,
  propsMapper: (...props: any[]) => Object,
  renderPropName?: string
): HigherOrderComponent

이 함수는 Render Props 를 사용하는 컴포넌트를 HOC 로 변환해주는 함수입니다. 첫번째 파라미터는 우리가 사용할 Consumer, 두번째는 넣어주고 싶은 값들을 설정하는 함수, 그리고 세번째는 props 이름 (Render props 를 사용 할 때 "children" 을 사용하는지 "render" 를 사용하는지) 를 넣어줍니다. 기본값은 'children' 이니 지금 우리는 따로 값을 지정해주지 않아도 됩니다.

한번, fromRenderProps 를 사용하면 어떻게 작성할 수 있는지 확인해볼까요?

import React from "react";
import { AnotherConsumer } from "../contexts/another";
import { fromRenderProps } from "recompose";

const Counter = ({ number, increment }) => {
  return (
    <div>
      <h1>{number}</h1>
      <button onClick={increment}>더하기</button>
    </div>
  );
};

const enhance = fromRenderProps(AnotherConsumer, ({ state, actions }) => ({
  number: state.number,
  increment: actions.increment
}));

export default enhance(Counter);

아까와 똑같이 잘 작동하나요?

Edit Context Tutorial

results matching ""

    No results matching ""