夢のかけら

Railsエンジニアの技術ブログ

【React】高階コンポーネントを使ってみる

f:id:lampler:20210605070153p:plain

高階コンポーネントって何?

高階コンポーネント高階関数と似ている。高階関数とは関数を戻り値とする関数のこと。

高階コンポーネントは引数でコンポーネントを受け取り、戻り値として新しいコンポーネントを返す関数のこと。

どんな時に使うの?

クラスの継承と似ていると思う。親クラスに状態(state)やメソッドを定義して、子クラスで使い回す。似たような処理を機能を持つコンポーネントを複数個作成する時に使える。

サンプルコード

ルートのコンポーネント:App.js

import Movie from './hoc/Movie'

function App() {
  return (
    <Movie id={1}/>
  )
}

export default App

高階コンポーネント:withTooltip.js(withから名前をつけるのが慣例) 引数で受け取るコンポーネントの親になる。

import React from 'react'

function withTooltip(Component) {
  return class withTooltip extends React.Component {
    state = { showTooltip: false}
    mouseOver = () => this.setState({ showTooltip: true })
    mouseOut = () => this.setState({ showTooltip: false })

    render() {
      return (
        <div>
          <p>マウスを乗せると答えが出るよ</p>
          <Component
            onMouseOver={this.mouseOver}
            onMouseOut={this.mouseOut}
            showTooltip={this.state.showTooltip}
            {...this.props} // 親からもらったデータを全て渡す
          />
        </div>
      )
    }
  }
}

export default withTooltip

最下層の子コンポーネント: Movie.js

import React, { Component } from 'react'
import withTooltip from './withTooltip'

class Movie extends Component {
  render() {
    return (
      <div>
        <span>id: {this.props.id}</span>
        <p
          onMouseOver={this.props.onMouseOver}
          onMouseOut={this.props.onMouseOut}
        >
          高級コンポーネントとは?
        </p>
        {this.props.showTooltip && <p>コンポーネントを返す関数だよ</p>}
      </div>
    )
  }
}
export default withTooltip(Movie)
// 戻り値はWithTooltipにラップされたMovieコンポーネント
// つまりMovieコンポーネントを子に持つWithTooltipコンポーネントである

親子関係はこの通り。Appで渡したidもしっかりとMovieへ渡すことができている。

f:id:lampler:20210605065947p:plain