GitHub最近、ReactやdekuといったViewのコンポーネントの仕組みを持ったライブラリを使って、NW.jsやElectronで動くようなアプリを書いたりしています。Classesで書いている場合にthisをbindする必要が多くなる気がします。Classesを使うよりは、React.createClassを使ったほうが楽になるようにも思えます)特にFlux的なStoreの変更した時にハンドラを登録したいときにthisでbindした関数を登録すると、ハンドラを解除するときに面倒なことが起こります。}だとイベントが解除できないという問題が起こります。そのため、事前にbind済みのハンドラを持っておく必要が出てきたりします。使って書くの3つ書いてみます。thisを普通にbindする手法これは単純で毎回bindすると===で異なる関数が返すため、constructor(){}などで一度だけbindして、それを使いまわすという形で書くことができます。先ほどのbindした結果は新しい関数を毎回作るため、ハンドラの登録と解除がそのままできないという話だったので、azu/idempotent-bindというものを書いてみました。azu/idempotent-bindは以下のように、同じ関数とthisの組み合わせだとunbindするまで同じ結果を返すbind関数です。this);これを使うと先ほどのコードは、以下のように書けるようになるのでちょっとだけ短くなります。ClassesまたはReact.createClassを使って書くので、いわゆるクラスっぽいもので書く感じになっています。クラスで書くとクラス内のメソッドを参照するのにthis使うため、必然的にthisが多くなることがわかると思います。Reactのようなコンポーネントを扱うdekuというライブラリでは、このthisの問題をクラスではなく関数でコンポーネントを書くことで解決しようとしています。Reactdekuではコンポーネントはあるメソッドを持つただのオブジェクトであって、そのメソッドに対してproosやstateといったものが渡されるので、thisを参照する必要がない仕組みになっています。以下のようなオブジェクトが一つのコンポーネントで、Reactではthis.propsという感じで参照する部分が引数として渡ってきていることがわかると思います。}};dekuを使って先ほどのカウントアップボタンを書いてみると以下のように書くことができます。render}dekuもBabelの設定を一行加えるとJSXで書くことができます。elementを渡すか、babelrcに以下のような設定を追加することでJSXがdekuの要素を作成する関数に変換されます。dekujs/deku話を戻して、dekuによるコンポーネントを見てみると、thisが一切出てきてないことがわかると思います。dekuのコンポーネントはライフサイクルメソッドを持ったオブジェクトであればいいので、普通に関数として定義してやって、最後にオブジェクトとしてまとめれば良いことになります。コンポーネントを構成する関数に引数に必要なもの渡せばテストできるので、テストがしやすいというのがひとつの利点です。dekuもReactのようにライフサイクルで間違った使い方などをするとコンソールに警告と解決方法を書いたURLを出してくれたり、Reactとライフサイクルは殆ど同じだったり、JSXも使えるのでReactを書いたことある人はすぐに分かる感じのライブラリだと思います。min.jsが10kb程度でReactに比べて大分小さいことなど特徴はいくつかありますが、詳しくは以下を見てみてください。Reactおわりに今回作ったサンプルはReactとDekuのコンポーネントをそれぞれ作って、StoreとActionは同じものを共有して使っています。Componentでやってることが大分近い感じな気がします。Componentsを入れる予定もあるらしいので、この辺のコンポーネントの作りはまだまだ議論の余地がありそうですね。Programmingへの取り組みは模索中という感じです。bindの問題を構文的にサポートするES.nextのプロポーサルもありますが(Babelではオプショナルサポート)、今回の話は構文で解決する問題ではないので単純には行かない感じですね。タグ:JavaScriptDekuReactWebCompoentsお知らせ欄JavaScriptに関する最新情報は週一でJSer.infoを更新しています。efcl/efcl.github.ioからご意見下さい関連記事コメントを。