コンポーネントを関数に渡して新しいコンポーネントを返す場合、それは高階コンポーネント(HOC)と呼ばれます。 それが単純に聞こえるなら、それはそうです! そして、あなたのコードはそれらを使用するためにより簡単になります。

この投稿の過程で、高次のコンポーネントの抽象化によって、作業がより読みやすく、再利用可能で、構成可能になる方法がわかります。

いくつかの用語

先に進む前に、の高次バージョンを作成しているものを定義しましょう。 これらの定義は同じ意味で使用されているように見えるかもしれませんが、それらの違いに注意することが重要です。

  • Node :DOMにマウントされたHTML要素。 ブラウザがそれをレンダリングしており、JavaScriptがそれを操作できます。
  • Instance :コンポーネントクラスのランタイムインスタンス。 これらは、メモリ内のJavaScriptオブジェクトとして表されます。
  • Element :ノードまたはインスタンスになる可能性のあるものを説明するマークアップのビット。 Reactでは、これらはJavaScriptオブジェクトにトランスパイルされ、実行時にインスタンスになります。
  • Component :要素の抽象化。 それらはいくつかの内部状態を持っているかもしれません、そしてそれらは彼らが受け取る小道具に応じて異なった振る舞いをするかもしれません。 レンダリングを求められると、コンポーネントは要素を返します。
  • 高階コンポーネント(HOC):コンポーネントの抽象化。 コンポーネント(およびおそらく他のいくつかのパラメーター)が与えられると、それらは新しいコンポーネントを返します。

飛び込む

アプリのユーザーページで作業を開始しようとしているとします。 User オブジェクトがどのように見えるかはわかっていますが、使用する認証の種類はまだ決まっていません。 後で正しい道を決めるときに、どうすれば心痛を避けることができますか? ページがすでに完成している3か月後に、どのように考えが変わる可能性を予測しますか?

名前の付いた単純なHOC関数から始めることができます withUser. この関数は、渡されたすべてのコンポーネントをラップアラウンドし、Userオブジェクトを小道具として提供する必要があります。

const withUser = WrappedComponent => {
  class WithUser extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        user: sessionStorage.getItem("user")
      };
    }
    render() {
      return <^>{...this.props} />;
    }
  }

  return WithUser;
};<^>

説明:

  • 私たちの機能、 withUser、任意のコンポーネントを引数として取ります。
  • 内部では、 WithUser Userオブジェクトをから読み取るコンポーネントクラス sessionStorage そしてそれを状態に追加します。
  • レンダリング関数は、 WrappedComponent 状態からのユーザーpropを持つ新しい要素として。
  • アウターを渡す this.props 内側に WrappedComponent.

または、状態が不要な場合は、機能的なHOCを使用することをお勧めします。

const withUser = WrappedComponent => {
  const user = sessionStorage.getItem("user");
  return props => ;
};

HOCを使用する

ページ上のUserオブジェクトにアクセスする場合は、次のように呼び出すことができます。 withUser ページのコンポーネントをラップするには:

const UserPage = props => (
  <div class="user-container">
    <p>My name is {props.user}!</p>
  </div>
);

export default withUser(UserPage);

そしてそれはそれをします! 私たちの withUser 関数は引数としてコンポーネントを取り、より高階のコンポーネントを返します。 今から3か月後、状況を変えることにした場合は、HOCを編集するだけで済みます。

野生で

これまでHOCに慣れていなかった場合は、気付かずにHOCに遭遇した可能性があります。 いくつかの注目すべき例:

  • react-redux connect(mapStateToProps, mapDispatchToProps)(UserPage)
  • react-router withRouter(UserPage)
  • material-ui withStyles(styles)(UserPage)

ボーナス

The compose redux の関数を使用すると、複数のHOCを1つにまとめることができます。 例えば:

import { compose } from 'redux';
// ... other imports

export default compose(
  withStyles(styles),
  withRouter,
  withUser
)(UserPage);

この場合、スタイル、ルーター、ユーザーはすべて私たちに渡されます UserPage 成分。