JavaScript
reactjs

Reactの Higher-order Components (HoCs) という概念に関するメモ

More than 1 year has passed since last update.


Higher-order Components

ReduxなどReact関連のライブラリで時々出てくるHigher-order Componentsについて色々わかんなくなったので調べたことをメモ程度に留めてまとめる

通称 HoCとかHoCsとか略されるが、この記事では Higher-order Components、HoCsで統一しておく。


Higher-order Components(HoCs)とは?

語の元となったのは高階関数(Higher-order function)であると思われる。

高階関数は、「関数を引数にとり、関数を戻り値とする」ような関数の事。

HoCsも同様で、「Componentを引数にとり、Componentを戻り値とする」ような関数(または実装パターン)の事 1


なぜこんな概念が出てきたのか?

この記事が良く出される

Mixins Are Dead. Long Live Composition

ざっくり要約すると


  • ES2015のclass記法においては、mixinは使えなくなった

  • 今後、classのmixinが取り込まれる可能性はある

  • けど、mixinはそもそも色々モロい部分もある

  • 多分Reactに復帰することも積極的ではなさそう

  • そこで、Higher-order Componentsですよ。という話


Mixinって何?またはなんだっけ?

ちょっと忘れているのでおさらい。

ReactのcreateClassで利用できる、いわゆるMixin。

継承をせずに、Componentに同一の挙動を与えるものだった。


ざっくりどんな実装をしているのか?

https://gist.github.com/sebmarkbage/ef0bf1f338a7182b6775

HoCsの初出(らしい)こちらのGistがわかりやすい。

噛み砕いてコードリーディングしてみる


  • 登場するのはこの2つ


    • Enhancer = コンポーネントを受け取ってコンポーネントを返す関数。HoCs

    • MyComponent = 例として適応される側のコード



  • Enhancerを見てみる



    • Enhancer = (ComposedComponent) => class extends Component...という部分がかなり特殊に見える。

    • ワンライナーでやってるけどこういうことだよ」と展開後のコメントで書かれている

    • やっていることは「ComposedComponent」という元のComponentを受けて、匿名のクラス(class extends Component)を返している

    • この時に、componentDidMountだったり、stateの利用だったりをして、mixinがやっていたようなことをやっている




  • export default Enhance(MyComponent)で、HoCs適応済みのComponentを返している。

ということで、やっていること自体はとても簡素。好みによってはprops.childrenでも代用出来るかもしれない(多分コードの簡素さと、DOMが深くならないとかの理由でclassでwrapしてる方を採用しているんだと思う)。


各ライブラリにおける実例

HoCsは、Reduxやらreact-routerやら有名ライブラリで使われている。以下見つけられた例。


HoCs に関する記事、参考文献など





  1. 「関数を適応したComponent」を指している場合もある。若干このあたり理解甘い。