Help us understand the problem. What is going on with this article?

Componentを拡張してみる

More than 5 years have passed since last update.

今回はちょっとした小ネタとして、既存の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について書きたいと思います。

koba04
smarthr
社会の非合理を、ハックする。
https://smarthr.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away