Code

2016年3月6日日曜日

React.js Modal Component の作り方

 いろいろ忙しいです、最近は。プロジェクトのリリースは一ヶ月伸ばされました。ビジネス側はログイン機能がほしいと言ってきたので、五月のプランに入っている Authorisation / Authentication 機能を3月いっぱいで開発することになりました。そのログイン機能はモーダルをポップアップして、ページの真ん中に表示することになっています。
 ライブラリを使おうと思ってましたが、調べてみたら、React.js 版はあまり内のプロジェクトにあわないなと思いました。それで、自分で作ろうと思いました。
 まず、そのモーダルポップアップは一つになるべきです。つまり一ページの中に一個だけにしたいです。そうすると、children を変えることで、いろんなポップアップが表示できます。次、ページの真ん中に表示するにはまず div とその overlay が必要です。
    <div className={ "modal" + this.props.showModal ? " active in" : "" }>
        {this.props.children}
    </div>
    <div className="overlay"></div>
 もちろん、overlay は pseudo-element でもできます。
 簡単ですね。:)ポップアップするときに、props.showModal を使って、active in class を追加して、画面に表示します。
 そのあとは close ボタンなどを作るだけです。
 まぁ、もし children にクローズボタンとか入れる場合、React.cloneElement を使ったりして、props を追加すればいいですね。

 AngularJS と比較すると、テンプレートベースのモーダルは ng-include を使えば、同じことができます。
 ここで、React.js のいいことは、re-render は速いです。すでにレンダリングした Component をもう一度レンダリングする場合、children の type をまず React.js を比較して、もし違うタイプだったら、ツリー全体を更新しますが、もし同じ Component の場合、更新するだけです。DOM 操作は最小限に抑えています。
 逆に AngularJS の場合、ng-include はテンプレートの string をチェックしていますので、変わってない場合は Dirty Check でスキップされます。つまり、モーダルが更新されないのです。ここで、ng-include を一回クリアするか、$timeout を使って、リフレッシュしないといけません。または自分でその テンプレートの scope 引数を親から変更したりして、更新します。また Dirty Check が一つ増えます。
 React.js の場合、わかりやすいですし、AngularJS 1.0 は面倒くさいなと。AngularJS 2.0 では scope の ダイジェスト対象が設定できるようになるので、速くなると思いますが、やはり、Component という概念は上だと思います。
 来週 Polymer を見てみよう。