React+TypeScript+jQueryの共存(3)

React+TypeScript+jQueryの共存(3)

TypeScriptに置き換えていく!

React+TypeScript+jQueryの共存(2)の続きです。

今回見ていくのはこちら、Tag.jsxです。

var React = require('react');

//タグ
var Tag = React.createClass({
  handleAjax: function() {
    apiURL = './api/article?tag=' + this.refs.tag.name;
    $('.overlay').removeClass('overlay');
    $('#overlay').css('display', 'none');
    $('#overlay-close').css('display', 'none');
    $('#spinner').css('display', 'block');
  },
  render: function() {
    return (
      <li><a ref="tag" name={this.props.id} onClick={this.handleAjax}>{this.props.tag}</a></li>
    )
  }
});

//タグリスト
var TagList = React.createClass({
  render: function() {
    var tagNodes = this.props.data.map(function(tag) {
      return (
        <Tag tag={tag.name} id={tag.id} key={tag.id}/>
      )
    });
    return (
      <ul className="tag-list">
        {tagNodes}
      </ul>
    )
  }
});

module.exports = TagList;

これをTypeScriptに置き換えます。

クリックイベントがおかしい?

前回やったとおり、classのところを書き換えて…

class Tag extends React.Component<any,any>

とする…のは大丈夫ですね。

でもエラーが出まくります。

このTagコンポーネントの中で、onClick={this.handleAjax}というのがあるのですが、こいつがどうも動きません。

handleAjax: function()

とか

render: function()

とかがエラーになります。
どうやら書き方が変わるみたいですね。

handleAjax(){}

render(){}

だけで良いようです( ゚д゚)!

それから、これまでfunctionの区切りごとについていた「,」も必要ないみたい。

var React = require('react');

//タグ
class Tag extends React.Component {
  handleAjax() {
    apiURL = './api/article?tag=' + this.refs.tag.name;
    $('.overlay').removeClass('overlay');
    $('#overlay').css('display', 'none');
    $('#overlay-close').css('display', 'none');
    $('#spinner').css('display', 'block');
  }
  render() {
    return (
      <li><a ref="tag" name={this.props.id} onClick={this.handleAjax}>{this.props.tag}</a></li>
    )
  }
}

…こうなりました。

でも、まだ動かない!

いろいろ調べてみると、onClickしたときには、thisをbindしてやらないといけないらしいです。
ここを書き換えます。

      <li><a ref="tag" name={this.props.id} onClick={this.handleAjax.bind(this)}>{this.props.tag}</a></li>

ちなみにこれ、ほかにもやり方があるみたいで、consructor()でまとめて指定しておくこともできるようです。
URLForm.tsxのTagFormコンポーネントで使ってみました。

//新規タグ入力フォームコンポーネント
class TagForm extends React.Component<any,any> {
  constructor() {
    super();
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleEnterSubmit = this.handleEnterSubmit.bind(this);
  }

//略

  render(){
    return (
      
); } }

それから、jQuery使ってるとよく、引数にe入れてe.stopPropagation()とか、e.preventDefault()とかしますね。
あれもそのままではうまくいきません。
eってなによ?ってエラー出ます。
そこで、e自体にもちゃんと型定義をしてあげないといけません。

handleEnterSubmit(e:any){
    e.stopPropagation();

//略

雑ですね!

何を指定したらいいのかわからないからとりあえずanyにしておきました。
とにかくコンパイル通るまではany振りまいておく!

あと、privateとかつけておくこともできるそうです。

  private handleEnterSubmit(e:any){
    e.stopPropagation();

//略

とりあえず今回はここまで!
次回はref属性の問題と、map()がうまくいかない問題を片づけた話です。

React+TypeScript+jQueryの共存(4)