Higher Order Componentsとは
自分の雑な理解では react componentをラップして様々な拡張性を与えられるテクニックのこと
詳しくはこちらを読むとわかると思います。
ReactのHigher Order Components詳解 : 実装の2つのパターンと、親Componentとの比較
http://postd.cc/react-higher-order-components-in-depth/
propsをrenderした後から更新したくなった
離れた場所にrenderしたcomponent同士をどうにか連携できないものか(この設計の是非は脇に置いといてください…)という課題がありまして、
例えば2カラムのレイアウトのページで、メインカラムとサイドバーにそれぞれcomponentをrenderしていたとします。
サイドバーの何かをクリックすると、メインカラムの内容が変化するようなものです。
Higher Order Componentsを試してみる
単純なHigher Order Components(以下HOC)はこれだけです。
// nameプロパティが必須なコンポーネント
class Test extends React.Component {
static get propTypes() {
return {
name: React.PropTypes.string.isRequired
};
}
render() {
return (
<div>{this.props.name}</div>
);
}
}
// これが Higher Order Components を行う関数
function hoc(WrappedComponent) {
// ローカルコンポーネントを定義して返す
return class HOC extends React.Component {
render() {
// ローカルコンポーネントで対象のコンポーネントのReact elementを返す
return <WrappedComponent {...this.props} />;
}
}
}
const enhancedTest = ReactDOM.render(
React.createElement(hoc(Test), { name: "kozo" }),
document.getElementById("app")
);
このように単に関数内のローカルコンポーネントのrenderで受け取ったコンポーネントのReact elementを返すだけです。
このままだと特に何もできないのですが、自分は以下のようにすることでrender後にコンポーネントの外から、
つまりプレーンなjavascriptの世界からコンポーネントを操作できるようになりました。
function hoc(WrappedComponent) {
return class HOC extends React.Component {
constructor(props) {
super(props);
// 敢えてpropsとして渡された値をstateにセットする
this.state = props;
}
render() {
// stateの内容をpropsとして渡す
return <WrappedComponent {...this.state} />;
}
}
}
const enhancedTest = ReactDOM.render(
React.createElement(hoc(Test), { name: "kozo" }),
document.getElementById("app")
);
// 任意のタイミングでTestコンポーネントのpropsを書き換え可能に
enhancedTest.setState({ name: "yamagata" });
これで別のコンポーネントの onClick
などをトリガーにコンポーネントの外側から自由に操作が可能になりました。