November 25, 2020
複数のHOCでラップしたい時、composeを使えば読みやすい
Reactのコンポーネントを複数のHOC(High Order Components)でラップしてしまうと、ネストが深くなっていき、読み辛くなることがありますよね。いつも「あれ、どうするんだったっけ?」となってしまうので、ここにメモっておきます。
Updated at December 24, 2020
Reactのコンポーネントを複数のHOC(High Order Components)でラップしてしまうと、ネストが深くなっていき、読み辛くなることがありますよね。
いつも「あれ、どうするんだったっけ?」となってしまうので、ここにメモっておきます。
HOC(High Order Components)とは?
HOC(High Order Components)とは、他のコンポーネントをラップするReactコンポーネントのことです。
ラップされたコンポーネントを受け取り、新しいコンポーネントを返す関数ですね。
よく見かけるMaterial UIの例。
import React, { Component } from "react";
import { withStyles } from "@material-ui/core/styles";
const styles = {
root: {
color: `red`,
},
};
class MyComponent extends Component {
render() {
return <div className={this.props.classes.root}>コンテンツ</div>;
}
}
export default withStyles(styles)(MyComponent);
これらのHOCを利用しているライブラリはよく見かけます。
- react-redux →
connect()
- material-ui →
muiThemeable()
- redux-form →
reduxForm()
- react-router →
withRouter()
複数のHOCでラップ
開発を進めていくと、こんな感じで複数のHOCでコンポーネントでラップする必要がでてきます。
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
import { withStyles } from 'material-ui/styles'
import withWidth from 'material-ui/utils/withWidth'
class MyComponent extends Component {
// ...
}
export default withRouter(withStyles(styles)(withWidth()(MyComponent)))
しかし、深くネストしていて、可読性が非常に低い…。
解決するには?
それを解決するには、recomposeライブラリの compose
コンポーネントを使用します。
まずはパッケージをインストールしましょう。
コマンドライン
npm i recompose
先にあげた例を書き換えると、こんな感じ。
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
import { withStyles } from 'material-ui/styles'
import withWidth from 'material-ui/utils/withWidth'
import compose from 'recompose/compose'
class MyComponent extends Component {
// ...
}
export default compose(
withRouter,
withStyles(styles),
withWidth()
)(MyComponent)
すっきり見やすくなりました✨
※上から順番に実行されます。
compose
を使用することで、よりスマートに書くことが出来ますね。