Higher Order Componentについて調査
はじめに
Higher Order Componentについて学習。
atomic Designと呼ばれるものを実現するよい手法なのだろうと感じ、
使い方を少し学ぼうと思ったので、その記録を。。。
ゴール
- MyButtonを拡張して、MyCustomButtonコンポーネントをつくる。
ポイントは、styleをどうやって拡張させることができるのかということである。
MyButtonについて
MyButtonは、赤色の単純なボタンコンポーネントである。
MyButton.jsx
// @flow import * as React from 'react'; type PropsType = { children: React.Element<any>, style: Object, }; // デフォルトstyle情報 const defaultStyle = { backgroundColor: 'red', }; export default function MyButton(props: PropsType): React.Node { const { children, style } = props; // デフォルトstyleとpropsで指定されたstyle情報を結合 const Style = { ...defaultStyle, ...style, }; return ( <button type="button" style={Style} {...props} > {children} </button> ); }
defaultスタイルとpropsから渡ってきたsytleを結合するのがポイント。
MyCustomButton
MyCustomButtonは、MyButtonの特徴を受け継ぎながら独自のスタイルをもったボタン。 背景色が青色になり、フォントサイズや文字色のstyle情報が新たに追加される。
MyCustomButton.jsx
// @flow import * as React from 'react'; import MyButton from './MyButton'; // Enhance関数は、Componentを引数にとり、コンポーネントを返す関数を返す function Enhance(Component): (Object) => React.Node { return props => ( <Component {...props} style={{ backgroundColor: 'blue', fontSize: '50px', color: 'white', }} /> ); } // HOC const MyCustomButton = Enhance(MyButton); export default MyCustomButton;
Enhance関数のように、関数を返す関数は、高階関数(Higher Order function)と呼ばれる。
このHigher OrderであるEnhance関数によりできた新たなコンポーネントこそ
Higer Order Componentということになる。
childrenがpropsに存在するが、HTML要素にchildren属性はつかなく、またMyCustomButton内では、propsをそのまま伝達するだけでよいので感心する。
App.js
ReactDOM.render( <div> <MyButton>PUSH!!</MyButton> <MyCustomButton onClick={() => {console.log('CUSTOM')}} > CUSTOM </MyCustomButton> </div>, document.getElementById('root'), );
各ボタンの表示結果は以下の通り。 MyCustomButtonで追加されているonClickも問題なく動作する。
気になること
class属性が付与されると、どちらのスタイルが優先されるのだろうか? これについても調べていこう。