LoginSignup
4
2

More than 3 years have passed since last update.

React高階コンポーネント(HOC)について

Posted at

はじめに

業務でReactを利用していますが、高階コンポーネントについて学んだことを備忘録を兼ねて投稿します。

高階コンポーネントとは

あるコンポーネントを受け取って、新しいコンポーネントを返す関数です。
高階関数のコンポーネント版といった感じです。

// 公式ドキュメント
const EnhancedComponent = higherOrderComponent(WrappedComponent);

// react-redux
export default connect(mapStateToProps, mapDispatchToProps)(Component);

// react-router
export default withRouter(Component);

どういうときに使うのか

横断的関心事を処理する方法として利用します。
横断的関心事とはコンポーネントにまたがって処理しなければならない要素の事で、以下のような事柄を指します。

  • 認可・ログイン状態
  • ログ・トラッキング
  • 例外・エラー処理

例えばreact-routerでは、ルーティングに必要な機能をコンポーネントのpropsに渡すために、withRouterという関数が用意されています。

以下がwithRouterの実装ですが、ReactのContext APIを使い、ラッピングしたコンポーネントに対してRouterContextから購読した値をpropsに渡しているのがわかるかと思います。

/**
 * A public higher-order component to access the imperative API
 */
function withRouter(Component) {
  const displayName = `withRouter(${Component.displayName || Component.name})`;
  const C = props => {
    const { wrappedComponentRef, ...remainingProps } = props;

    return (
      <RouterContext.Consumer>
        {context => {
          invariant(
            context,
            `You should not use <${displayName} /> outside a <Router>`
          );
          return (
            <Component
              {...remainingProps}
              {...context}
              ref={wrappedComponentRef}
            />
          );
        }}
      </RouterContext.Consumer>
    );
  };
  ...
  return hoistStatics(C, Component);
}

まとめ

高階コンポーネントは、Reactのメジャーな周辺ライブラリでも採用されているテクニックですので、今後機会があれば利用したいと思います。
今まで横断的関心事にはミックスインが利用されてきましたが、こちらは現在推奨されない実装のようですね。別途記事にしたいと思います。
https://ja.reactjs.org/blog/2016/07/13/mixins-considered-harmful.html

参照

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2