blog.koba04.comkoba04's twitter accountkoba04's GitHub account

React v0.13.0 Beta1でclassでComponentが作れるようになった

2015/01/28 @koba04

React.js Confの前日にv0.13.0 Beta1がnpmにpublishされました。

http://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html

featureは色々あるみたいですが、↑のブログにはその1つとしてClassによるReact Componentの作成が紹介されていたのでそれについて書きたいと思います。

ちなみにReact.createClassを使う場合はこれまでと同じままで大丈夫なはずです。

ES6 Classes

React.createClassではなくて、ES6のclassを使って↓みたいな感じで書けるようになります。

import {React} from 'react';

export class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.state = { val: props.foo * 2 };
  }
  onClick() {
    this.setState({ val: this.state.val * 2 });
  }
  render() {
    return (
      <div>
        <p>state is {this.state.val}. props is {this.props.foo}</p>
        <button onClick={this.onClick.bind(this)}>click</button>
      </div>
    );
  }
}
Hello.propTypes = {
  foo: React.PropTypes.number
};

ポイントとしては

  • React.Componentをextendsします。
  • constructorpropsが引数として渡ってくるのでそれを使って必要に応じてstateの初期化をする。
    • getInitialStateは使うことができません。(warnが出ます)
  • Autobindingはされなくなったので明示的にthis.onClick.bind(this)のようにする必要があります。
  • propTypesdefaultPropsはconstructorのpropertyとして指定する必要があります。
  • 現時点でmixinはclassで書いた場合は使うことができません。

といった辺りです。

変換

ES6のコードの変換は、これまで通りreact-toolsでjsxの--harmonyoptionを有効にしたり6to5使ったりする感じです。

今後

今の書き方だと微妙に感じるところも結構あるのですが、最終的には↓のような形で書けるようにしたいみたいです。

import {React} from 'react';

export class Hello extends React.Component {
  propTypes = { foo: React.PropTypes.number };
  state = { val: this.props.foo * 2 };
  onClick = () => {
    this.setState({ val: this.state.val * 2 });
  };
  render() {
    return (
      <div>
        <p>state is {this.state.val}. props is {this.props.foo}</p>
        <button onClick={this.onClick}>click</button>
      </div>
    );
  }
}

mixinについてはreact-futureを見る限りこんな感じになるのかもしれないですね。

https://github.com/reactjs/react-future/blob/master/01%20-%20Core/02%20-%20Mixins.js

import { mixin } from "react-utils";
import { Component } from "react";

const A = {
  componentDidMount() {
    super();
    console.log('A');
  }
};

class Hello extends mixin(Component, A) {
  render() {
    return <div />;
  }
}

CoffeeScript & TypeScript

ちなみにES6だけでなく、CoffeescriptやTypeScriptのClass syntaxでもかけます。


React.js自体でやることを減らしてES6、7のfeatureに任せることが出来るところは任せようといった方向性を感じて個人的にはいいんじゃないかと思っています。

React.js Conf行きたかった...