フロントエンドの変化とReact

石橋啓太氏(以下、石橋):よろしくお願いします。今日は「コンポーネント開発で変わったフロントエンドとrecompose」というタイトルで、お話をさせていただきます。

簡単に自己紹介しますと、DMMの石橋と申します。GitHubやQiitaではusagi-fという名前でいろいろ活動をしています。ずっとフロントエンドをやっているエンジニアです。

少し前ですが、3月の末に、今日のイベントの協賛でもあるマイナビさんで、Reactの開発現場向けの書籍を出版しました。

React開発 現場の教科書

デザイナーさんやフロントエンドに興味があるサーバーサイドのエンジニアなど、すでに本格的にReactを書いてる人というよりは、これから開発現場でどんどん導入したい人向けの内容になっています。

基本的なReactの仕組みと、今日のキーワードの1つでもあるAtomic Designの話も少し盛り込んだうえで、実際に現場で使うために必要なその他諸々の知識と、型とかテストとか、そういったところも含めて網羅的に書いてます。

今日、プレゼント用と見本用に数冊いただいてます。たぶん中身がどんなものか気になる方も多いと思うので、後の交流会で脇に置いてますので、ぜひ手に取ってパラパラ見ていただけるとうれしいです。

React人口は増えている?

じゃあ、本題です。目次としては、フロントエンド開発の今・昔がどう変わったかというところを簡単に振り返った後に、今日のキーワードのReactとAtomic Designの話を少し、個人的な感想も踏まえて、させていただきたいと思います。

後半はReactの実装まわりの話をしたいんですが、ちなみに、今日来ていただいてる方の中で「もうReactがっつり書いてます」って人はどれぐらいいらっしゃるんですかね?

(会場挙手)

半分ぐらいですか。ちなみに「Atomic Designも実践してます」という方は?

(会場挙手)

けっこういらっしゃいますね。ありがとうございます。最初イベントの情報を公開したときは、まだ書いたことない人が多いだろうなってイメージだったんですけど、想像の3倍ぐらいのスピードで埋まってしまったので、書いてる人はかなり多くなってきてるのかなという印象です。

まずは振り返りからさせていただきます。(スライドを指して)左側が、昔のフロントエンド開発に対する自分の印象です。

サーバーサイド側にViewの実装もされていて、フロントエンドの実装といえば、jQueryとかを使って、インタラクションとかを付けていったり、JavaScript内でHTMLを組み立てていくものが多かったように思います。

マイクロサービス化が進んでいる

比較して、右側では「マイクロサービス」という言葉を使ってますが、フロントエンドの世界でもマイクロサービス的な実装が進んでいるのかなと思ってます。とくに、今日のキーワードでもあるコンポーネントをいろいろ活用して、フロントエンドの中も設計していく時代になってきている感じですね。

じゃあ、そこがどうして、何がきっかけで変わったのかを、自分でも振り返ってみたんですけど、ポイントは、レンダリングのアルゴリズムっていう考え方が出てきたことが大きいんじゃないかと思います。

これはUIを宣言的に実装できるというところが大きな特徴で、それによって、UIにデータを渡して、最終的に描画されるものが変わる仕組みなんですが、これによって、更新した場合の差分という概念が出てきました。

これによって、今までのDOMツリーとそれを描画するための状態データを分けて考えることができます。これまではHTMLを書いていくことが中心だったんですけど、それと比較して、状態データをどのように管理するかが、フロントエンド側の実装の肝になってきたと思います。

じゃあ、実際に何が変わったのか。まず、フロント側でも複雑な設計がしやすくなったので、単純にできることが広がった。その代わりだんだん他の仕事が増えてきて、みたいな状態でもありますが(笑)。

実装は職人芸から設計の時代へ

それプラス、UNIX哲学みたいな、これまでのプログラミング界のノウハウを適用しやすくなってきたと思ってます。とくに「小さいものは美しい」とか、そういったところがコンポーネントの開発にかなり適用しやすい考え方かなと思います。

それと、宣言的な実装は再現性も高いので、デバッグとか、テストとか、そういったところでもかなり活躍している記述だと思います。

昔は、CSSとかやってきた方はかなり多いと思いますけど、職人芸みたいな実装を求められることが多かった。今は、ちゃんと設計してきちんとフロントエンドを組み立てていきましょう、きちんと戦略を練ろうという時代になっている。これが今と昔を比較した感想です。

じゃあ、実際のReactとAtomic Designの話に入っていきます。まずReactですが、出てからもう数年経って、いろいろ言われてはいますが、端的に表現すると、UIの構築を抽象化するものだと私は思ってます。

さっきも出てきましたけど、宣言的に関数を実装するのがReactです。これは本にも少し書きましたが、ReactのViewをつくるときには、関数に対して、あくまでも引数としてデータを渡してあげる。そうするとViewができあがる、というのがReactの基本的な考え方です。

UIの構築に専念できるようになった

もう1つReactの根底にあるのは、小さくつくって、それを組み合わせていくという考え方です。実装に必要な処理をどのように分けて、責務を分離して1つのものをつくっていくかが、実装においては重要です。

(スライドを指して)さっきの図を借りると、この上の部分が、UIを抽象化してつくっていく部分ですね。

下は、Reactのライブラリ側が自動的に生成してくれる、差分を取って更新してくれるところなので、実際アプリケーションをつくるときには基本的に触らなくていい部分です。ライブラリをアップデートすると、自動的に効率化される領域です。

これで、アプリケーションとかを構築するとき、昔やってたようなHTMLで具体的に描画する作業は、ライブラリに任せてしまえるようになりました。本来僕らが一番やらなきゃいけない、UIをどういうふうに宣言していくかというところに注力できるようになってきたと思います。

なので、Reactを書くときは、HTMLを書いていくというより、Reactという概念で書くような雰囲気で実装していくことになると思います。

とくにReactの場合、他のライブラリに比べると純粋な関数でできているので、単純にプログラムとしてどういうふうに関数を組み合わせるといい実装ができるのか、という観点で実装に入れるのが、僕は好きな部分ですね。

Atomic Designはコミュニケーションツール

次がAtomic Designです。今ここですべてを語るのは時間的に難しいので簡単になりますが、UIを上位下位みたいなかたちで分類して定義付けできるのがAtomic Designです。

これでどういうことが期待できるかというと、今までは、UIデザインってけっこうフワフワしてるというか、担当してるデザイナーに左右されてしまうところがかなり大きかったと思うんです。そこにこういう理論を利用することで、今後エンジニアとデザイナーの協業みたいなところで、なにかしらヒントを見つけやすくなると思います。

個人的な感想も入るんですけど、Atomic Design自体は、なにか決められたルールがあってその通りにつくればメリットがあるというものとはちょっと違って、あくまでもチーム内でコミュニケーションするときのツールという役割が大きいと思います。

とくに、デザインを理論的に組み立てられるので、今まで設計といったらコーディング側に寄った話が多かったのが、そこにUIデザインという側面も含めて一緒に設計ができるので、かなり未来があるのかなという気持ちもあります。

ただ、けっこう難しいんですが、実際どういう構造でできてるかという前提を持って、デザイナーとエンジニアが話してるという時点で、ある程度は、現時点では、やりたいことにけっこう近いのかなという気もしてます。

シンプルなコンポーネントでの実装が可能

ここからReactの実装寄りの話をしたいと思います。一般的なプログラミングの世界で、高階関数というものがあります。

「関数を引数に取って、関数を返す関数」という、ちょっと何言ってるかわからない人もいると思うんですけど。

少しソースコードがわかる人は、見てもらうと「こういうことかな」とわかると思うんですが。(スライドを指して)一番上のwithSomething関数、これは引数に関数を取っていて、リターンでまた関数を返してます。そのwithSomethingに別の関数を渡してあげて、別の関数ができあがる。関数を組み合わせてつくってるんですね。

この高階関数、英語にするとHigher-order Functionですが、これをReactの世界でも積極的に使っていきましょうというのが、Reactの公式が推している実装方法です。

今の関数をコンポーネントにすげ替えて読んでみると「コンポーネントを引数に取って、コンポーネントを返す」と。

実装も今、1つ前に言ったものとほぼほぼ同じで、引数の部分がコンポーネントに変わっています。それで、最終的にレンダリングするときに、もともと渡したかったラベルの値とかを渡してレンダリングする。

じゃあ、実装するとき、どこがどうなってて何がいいのかを少し解説します。本来UIに付けたくないけど付けなきゃいけない、副作用みたいな特殊な実装が、大きいアプリケーションをつくっていくとどうしても出てくるんですが、(スライドを指して)それを一番上のところで、関数として別のところに逃がしてます。

UIコンポーネントが単純になる利点

それができると、真ん中の部分、ボタンのコンポーネントは、本来やりたかった「どういうUIを描画するか」というところだけに絞った、シンプルなコンポーネントで実装できます。それを掛け合わせているので、デザインも含めた設計をAtomic Designとかでしていた場合、こういったアプローチは相性がいいと思ってます。

最後に少し紹介なんですけど、recomposeというパッケージがあります。

これはReactで実装していく中で、頻発するパターンがあるんですが、それを今の高階コンポーネント、HOCのパターンで実装するときに使える、ヘルパー関数をたくさん提供しているユーティリティパッケージみたいなものです。

(スライドを指して)これが、そのrecomposeを含めた実装コードの例です。

まず、上のほうにステートレスなコンポーネントが1つあったとします。

それにステートとか、それを操作するイベントハンドラみたいなものを後付け実装するときに、recomposeから提供されているwithStateとかwithHandlersというメソッドを使って、定義した後付けの要素をさらにcomposeメソッドでラップして、enhancer関数という、副作用がすべてまとまった関数みたいなものをつくることができます。これをReactのコンポーネントにガッチャンコした状態でエクスポートする。

UIを抽象的に考えるやり方が増えている

こういった実装ができると何がうれしいかというと、UIコンポーネント自体から余計な値とか実装を省きやすくなるので、直接的にUIの再利用性が高まってきます。そうすると、テストがしやすいとか、ゴチャゴチャな実装にならないという利点が生まれてきます。最終的には、Atomic design の設計とかにも、実装面が準拠しやすくなってくると思います。

まとめとして、今話したようなUIを抽象的に考えて実装していくものが、これから本格的に普及していくような下地ができてきていると思います。

知ってる方も多いと思うんですけど、Web Componentsとかも標準実装されてきてますし。少し前には「react-native-domってパッケージがすごいぞ」みたいな記事がバズってたり。これはReact Nativeの文脈を汲んでるんですけど、それをまたWebの世界に持ってきて実装できるという、ちょっとおもしろいものがあったり。あとは、UIライブラリでけっこう有名な、material-uiとかもコンポーネントの開発の最たるものかなと思います。

今、Reactみたいな薄く実装するライブラリが他にもすごく多く出てきてるので、興味ある方がいましたら、この後トークセッションもありますし、交流会でも話ができればと思ってます。

以上です。ご清聴ありがとうございました。

(会場拍手)