LoginSignup
4
2

More than 5 years have passed since last update.

React HOC お試しメモ

Last updated at Posted at 2018-02-06

3行で

  • Reactを使ってる
  • あるReactコンポーネントの下に多種のボタンが入るようなのを作りたかった
  • HOCを知った

HOCとは

Higher Order Component の略。

公式ドキュメントはここ。

A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React’s compositional nature.

(意訳:HOCはReactでのコンポーネント再利用の進んだテクニックです。HOCは、それ自体はReact APIの一部ではありません。それらはReactの構成上の性質から生まれるパターンです。)

とのこと。

Concretely, a higher-order component is a function that takes a component and returns a new component.
(意訳: 具体的には、HOCは一つのコンポーネントを取って一つの新しいコンポーネントを返す関数です。)

なるほど。ドキュメントの最初の方に書かれているこれを見るだけでとてもわかりやすい。

const EnhancedComponent = higherOrderComponent(WrappedComponent);

やってみる

なんとなくわかったところで、やってみます。

ボタンの種類を渡すとそのボタンを埋め込んだ特定のコンポーネントを返してくれるHOC

さて、今回必要だったのはボタンの種類を渡すとそのボタンを埋め込んだ特定のコンポーネントを返してくれるHOCです。つまりこんな感じでしょうか。

UserComponentWithSpecialButton.jsx
const UserComponentWithSpecialbutton = embedButtonInUserComponent(SpecialButton)

HOCで実装

使い方はなんとなくイメージできたので、ちゃんと書いていきます。Flowを使っているのでこういう感じになります。 1

embedButtonInUserComponent.js
// @flow
type User = {
  id: number,
  name: string,
};

type Props = {
  user: User
}

// この関数がHOC
// この場合は状態を持たないコンポーネント(いわゆるSFC)を返している
const embedButtonInUserComponent = (ButtonComponent: React.ComponentType<Props>) => {
  return (props: Props) => {
    return (
      <div className="user">
        <div className="user__name">
          <a href={`/users/${props.user.id}`}>{props.user.name}</a>
        </div>
        <div className="user__button">
           <ButtonComponent user={props.user} />
        </div>
      </div>
    )
  }
}

export default embedButtonInUserComponent;

HOCを使ってコンポーネントを作成

UserComponentWithSpecialButton.jsx
const UserComponentWithSpecialButton = embedButtonInUserComponent(SpecialButton);

export default UserComponentWithSpecialButton;

作成したコンポーネントを利用

SomeContainer.jsx
<UserComponentWithSpecialButton user={user} />

UserComponentWithXXXButtonみたいなものをそれぞれ作ってこういう感じで使える。

雑感

  • HOCはパターンとしての制約というか、こうやって書けよという方針がReactのドキュメントにきちんと書かれている
  • 特別な関数なので、hocs/ みたいな専用ディレクトリを切って管理していいのではないかと思うけどみんなどうやってるのか気になる

  1. Flowでこれ系の型を書くときはComponentTypeというのを使うらしい。詳細はHigher-order Components | Flowに書かれていた。 

4
2
1

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