LoginSignup
32
33

More than 5 years have passed since last update.

react.jsをes6で書くときのメモ

Last updated at Posted at 2015-08-12

React.jsはEcmaScript 6の記法で記述できます。ES6はより直感的な記法や明確なスコープなど、多くのメリットがありますが、React.jsで使うとちょっとした不便やノウハウが必要です。これはそのときのメモです。

イベントのコールバックのthis

次のようなコードがあります

my-component.jsx
class MyComponent extends React.Component {
    doSomeMethod() {
       // do something
    }

   handleClick(e) {
       this.doSomeMethod();
   }

   render() {
       return <RaisedButton onClick={this.handleClick}>button</RaisedButton>;
   }
}

このコードでボタンが押されたときに呼び出されるhandleClickのthisは、イベントの呼び出し元のオブジェクト(RaisedButton)になっています。このへんのスコープの感覚はES6と違うような…。

thisがMyComponentを指すようにするには、次のようにbindします。

return <RaisedButton onClick={this.handleClick.bind(this)}>button</RaisedButton>;

これで、イベントの発火時に呼び出されるhandleClickのthisはMyComponentのオブジェクトになります。

getInitialStateが使えない

以前の記述だと

var MyComponent = React.createClass({
    getInitialState: function() {
        return {key1: 1, key2: 2};
    },
    render: function() {
        return <RaisedButton>{this.state.key1}</RaisedButton>;
    }
});

のように記述してstateの初期値を設定していました。ES6の記法で書くと、getInitialStateは呼ばれません。stateの初期化はコンストラクタで行います。

class MyComponent extends React.Component {
    constructor() {
        super();
        this.state = {key1: 1, key2: 2};
    }

    render() {
        return <RaisedButton>{this.state.key1}</RaisedButton>;
    }
}

こちらのほうがより直感的ですね。
propsのデフォルト値の設定はもっと複雑らしいですが、まだ、試していません。

mixin

ES6ではmixinが使えなくなってしまいました。今のプロジェクトではReact Routerを使っていますが、transitionToのようなメソッドはNavigationをmixinすることを前提にしています。これ以外にもmixinを前提としているものがいくつかあり、使えないと不便です。
Rect Mixinはこの問題を解決してくれます。ただし、このプロダクトはホームページ上で

I can't think of a more elegant solution to mixins in es6 classes. If someone comes up with one, create an issue and I'll link to it here.

In the future people will likely use high order components instead of mixins, making this library obsolete.

Should you use es6 classes for react components? Based on the hacks required above, I'd probably avoid it. It's important that react makes it an option, and it's important to be able to use mixins with them, which is why this library exists.

と言っているようにmixinを暫定的に使うためのもので、将来は別の仕組みにおきかえられるべきものかもしれません。
mixinは次のようにりようします。

import React from 'react';
import ReactMixin from 'react-mixin';
import {Navigation} from 'react-router';

class MyComponent extends React.Component {
    handleClick(e) {
        this.transtionTo("someRouteObj");
    }

    render() {
        return <RaisedButton onClick={this.handleClick.bind(this)>Button</RaisedButton>;
    }
}
ReactMixin.onClass(MyComponent, Navigation);

これでNavigationをmixinできました。

willTransitionToなど

RouterでonEnterを使おうとしたら動きません。コードをみると次のようになっていて、onEnterはどのようにセットすべきものなかわかりません。

if (handler) {
    props.onEnter = handler.willTransitionTo;
    props.onLeave = handler.willTransitionFrom;
}

handlerのwillTransitionToを記述すれば目的の動作を達成できそうです。

class MyComponent extends React.Component {
    static willTransitionTo(transition) {
        if (this.state.someState) {
            transition.redirect("/");
        }
    }

    render() {
        return <RaisedButton>Button</RaisedButton>;
    }
}

classのメソッドないと動いてくれないので注意します。
主に認証が必要なページなどで遷移前に状態をチェックして、ログインページを表示するとかできます。本当はRouterで設定したかったんですけど…。

まとめ

現状、ReactをES6で記述するのは茨の道かもしれません。本当のサンプルコードもそのままでは動かないですし。
けれどもES6のわかりやすさはそのデメリットを差し引いても十分価値があるものです。JavaScriptが嫌いな私でも、この記法、わかりやすさであれば、フロントエンドの開発も苦ではなくなりそうです。

32
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
33