今回はちょっとした小ネタとして、既存のComponentを拡張したようなComponentを作りたい時の話をしたいと思います。
それには、v0.12で追加されたJSXのspread attributesを使うと簡単に出来ます。
テキスト付きの画像Component
例として、テキストと画像をセットにしたImageTextというComponentを考えてみたいと思います。
I/FとしてはimgのComponentに渡すものにプラスしてテキストで考えてみます。
var ImageText = React.createClass({
render() {
return (
<span>{this.props.text}<img src={this.props.src} width={this.props.width} height={this.props.height} /></span>
);
}
});
<ImageText text="名前です" src="/img/foo.png" width="100" height="200" />
単純に実装するとこんな感じです。とはいえ、imgにはaltも渡せたりするのでaltも...とか考えると面倒な感じになります。
こういった場合にspead attributesを使うとこんな感じで書くことが出来ます。
var ImageText = React.createClass({
render() {
var {text, ...other} = this.props;
return (
<span>{text}<img {...other} /></span>
);
}
});
この時渡すimgには関係ないProp(text)は渡さない方がいいのでtextとotherでspread attributesを使って分割しています。JavaScriptでも_.omitを使うことで同じようなことは出来ます。
これを使う場合、ComponentのI/Fがわかりにくくなるので、PropTypesをなるべく指定しておく方がわかりやすくていいと思います。
クリックイベントを送信するようにしてみる
次はクリックイベントを送信するようにしてみましょう。
var request = require('superagent');
var ImageText = React.createClass({
onClick() {
request.get("/click_img", { img: this.props.src });
},
render() {
var {text, ...other} = this.props;
return (
<span>{text}<img {...other} onClick={this.onClick} /></span>
);
}
});
こんな感じでonClick
を追加することでPropの値をmergeしてくれます。onClick
を{...other}
の前に持ってくるとonClick
の挙動を上書きされてしまいます。
これをJSXなしで実装する場合は、_.extendやObject.assignなどを使うことになります。
こんな感じでComponentを拡張したい場合はJSXのspread attributesを使うと便利ですというネタでした。
明日はmixinについて書きたいと思います。