3/22 (日) の rebuild.fm で React の話をしようと思っているが、その前に頭を整理するために React 雑感。雑感なので殴り書き。
React はこれ一つで複数の課題を解決しようとしている。そのため、人と議論してると話のコンテキストがぶれやすい。ざっくりは
- フロントエンドのプログラミングパラダイムを、サーバーサイドのような富豪的なスタイルに変える
- コンポーネント (雑に言うと独自タグ) 指向で UI を組み立てる
- ステートレスコンポーネントやメッセージパッシングで疎結合性を高めることにより、イベントの依存関係地獄を解消する。また結果的にテスタビリティを高める
あたりだろうか。
React というと最初に目につくのは VirtualDOM だけれども、VirtualDOM は 1 や 3 を達成するために障害となった技術的課題を解消するためのテクニックであってそれ以上でもそれ以下でもないように見えている。3 は React というより Flux まで含めた文脈だけれども。
この 1, 2, 3 のうち、プログラマ的にこれはいいなと感じる大きさで並べると 1 > 3 > 2 という感想。
逆に、触るまえに表面的にそういうことかなあと目がいったのが 2 > 3 > 1 という順番。「これはコンポーネント指向なんだなあ」→ 「ああ、ステートレスとかメッセージの方向とかに制約を持たせて信頼性を高めるのか」→「あ、サーバーサイドみたいに富豪的にやるっていうプログラミングパラダイムの転換なのか」という順番で気がついた。
1 について。これは多分自分が古いWebプログラマで、サーバーサイド脳に侵されているからだろうというのは多分にあるのだろうけど「データモデルに変更があったら View はいちから全部描画し直せばいい」というのは、View の状態管理をさぼって富豪的に設計すればいいということで、とても大きなメリットだと感じた。
リアルタイムネットワークアプリケーションの最たるものといえばチャットだけども、そういえばかつて 90年代とか 00年代初頭、Web ブラウザでのチャットというのは定期的にブラウザをリロードして新着を読み込むという、そういう原始的なものだった。あれから XMLHttpRequest が再発見されて、JavaScript がモダンになって、jQuery だ、WebSocket だ、node.js だ HTML5 だなんだといろいろあって、確かにブラウザをリロードしなくてもよくなった。しかしご存知のように、状態管理だなんだでプログラミングパラダイムはちょっと複雑になってしまった。けどこれが、考え方としては、ブラウザをリロードしてたときと同じように、データに変更があったら全部更新すりゃいいんだよ (DOM を特定して状態に併せて変更するとかそんなことしなくていいんだ) こまけえこたあいいんだよ (React の VirtualDOM が面倒みてくれるんだよ) ということである・・・なんというか、アーキテクチャのコモディティ感ある。万歳。
3 については、facebook の文書に書いてたけど、コードは書くよりも読まれる時間の方がずっと長い、だから見通しがよいことが重要なんだって、まあいわれてみたらその通りで、コードを読むときに把握しやすくなるというメリットが多分にある。ただ、実際書いてみるとそれより大きいには、自分のように js フロントエンドが本業じゃない (本業はマネジメントみたいです) エンジニアにとっては、どんな処理をどこに書けばいいかという方針が明確にある・・・ レールに乗れる感を提供してくれるのが大きい。
この 1 や 3 の作用に比べると、2 についてはどうでもいいというか、コンポーネント化はステートレスな View の実現とか、VirtualDOM を抽象化するためのインタフェースをどう考えるとかとか、それを突き詰めていった結果必然的にそうなっただけで、それ自体が嬉しいみたいな感じはあまりないというのが現時点の印象。 React Components とかで公開されてるコポーネントをバリバリ使う日が来たりしたらまた感想は変わるかもしれないけど。少なくとも「Web Components が Web 開発を変える!」みたいなコンポーネント指向に対するテンションみたいなうれしさは、あまり抱いてない。
Web Components 本家を少し触ってみたけど、HTML コンポーネントが再利用できるというメリットだけで、ほんとにこれがスタンダードになり得るだろうかという感想を持った。React のコンポーネント指向は、ここに述べたように(自分にとっては)副次的なもののように感じるが、それ以外の利点が大きいので、結果的にそれとの抱き合わせ販売的に React が Web のコンポーネント指向の勇になるかもしれないな、ということもちょっと感じた。
Flux について。
Flux は React で、データモデルを React の外に持ちたいという欲求を叶えようとすると必然的にそこに落ち着くんだな、という感想。
状態をもったものすなわちデータモデルを監視してモデルに変更があったら View を全部更新しなおし、ということをやっると当然だけれども、そのデータモデルを React コンポーネントの階層の外で管理したくなる。そこで Store があるといいねという話になる。じゃあその Store に対して、ユーザーの操作によって発生したデータの変更イベントを送りたい。そのイベントを React コンポーネントの階層の下の方からどうやって Store の参照を持つルートまで伝えるか・・・とか考え始めると、イベントの受け取り手もやはり階層の外にあったほうがよい。でも、Store に直接イベントを投げつけると、コンポーネントと Store の間の依存関係が複雑になるのは目にみえてる。なんで、あいだに Dispatcher を挟んで交通整理をしてもらう。
これが Flux に至る理由かな・・・という風にみた。そこに必然性を見てとれるので、Flux でコードを書くときにも迷いとか、そういうものが少ない。
現時点で課題に感じてることは
- サーバーサイド脳でいいじゃん、といいつつ View の構造 (要は HTML) が JavaScript のコードの中に、しかも断片的に分断されて紛れ込んでて、これホントにこれでいいの感
- 確か facebook 的には責務の分離じゃなくて技術の分離だ、みたいなことを言ってるんだっけ? ⇒ 確かにその辺を棄ててでも View の状態管理をしない考え方のメリットは大きいかなという気はしてる。なので、そのメリットを維持する前提で、テンプレートエンジンとかでこれまで培ってきたワークフローをどうするか (元に戻せるのか、別のやり方になるのか) おを考えていくんだろうなー、もやもや、イマココ
- コードは書く時間より読む時間の方が長いんだ! ・・・ というのは確かにその通りなんだけど、とはいえやっぱり書く量が多いなー
- React は生産性を高めるものではなく信頼性を高めるのだ、というのもわかるけども
- Convention over Configuration 的な考え方で、もうすこし手数を減らしつつ React や Flux をスポイルしない程度の実装が、今後出てくる余地というかのびしろはあるんじゃないかなと、にわかながらにそう思う
というわけで、React が決定版といいきるまでには至らないけれども、いろいろ js フレームワークが乱立する中で、まあこれは一度触っておいて損はないんじゃないかな、というものだとは思った。
なお、React を題材にリアクティブプログラミングについて語ろうとするのは地雷じゃないかという気がしているのでそれについては言及は避ける。