React Hooks公開から1年で得られた知見

西村爽氏:西村です。よろしくお願いします。『React Hooks公開から1年で得られた知見』ということで、株式会社ジェムクック(Gemcook)でHooksを導入するまでの経緯と導入後のメリットを語りたいと思います。

まず僕のプロフィールです。ジェムクックでフロントエンドエンジニアをしている西村爽です。ふだん主に使っているのはTypeScript、React、React Native、それからAWSです。最近はReact Nativeを書いていることが多いです。

趣味は囲碁をやっています。5歳くらいからやっていて、一時期棋院生でした。今でもオンラインで対局とかしているので、囲碁友達募集しています。

今日のアジェンダです。React Hooks概要ということで、React Hooksの基本的なことやメリットなどをおさらいします。次にGemcookのコンポーネントとHooksの歴史で、Hooks導入までの経緯とHooksを導入して何が変わったかを中心に話します。最後にまとめとして、今日のおさらいをします。

React Hooks概要

React Hooksの概要です。React Hooksは、React16.8.0以降で利用可能な関数コンポーネントのAPIです。かれこれ公開から1年ほど経っているので、使っている人も多いと思いますが、まず復習したいと思います。

その前に、なぜ関数コンポーネントなのか? というところを振り返っていきたいと思います。関数コンポーネントの何がいいのかを自分でももう1回考え直してみたんですけど、クラスコンポーネントはClass構文を使用していたり、thisやbindなどちょっと独特な構文を意識しないといけなくて、ちょっと複雑になりがちなのが煩わしかったというのも1つありました。

それに比べて、関数コンポーネントは、そのまま関数なので、非常にシンプルな記述ができてわかりやすいのがメリットだと思います。ただし、Hooks登場以前は、state、つまり状態をもつことができなかったので、そこがよくなかった。

React Hooksの登場で、stateが使えるようになりました。Hooksの登場で、関数コンポーネントが高機能になって、見通しのいいコードのままstateをもったりできるようになったので、コンポーネント間のロジックを簡単に再利用できるようになりました。

個人的には、ここのメリットが一番大きいなというふうに感じています。複雑になりがちなライフサイクルイベントや、フォームとかデータテーブルとかのちょっと複雑なロジックも共通化できるようになりました。

さらにテーブルとかで言うと、サービスごとにUIに依存せず、ロジックだけを書きたいなっていうところも大きいので、共通化して使用できるというのは、すごく便利になりました。

基本的なHook

基本的なHookを少し紹介したいと思います。React公式にも書かれているんですが、これらの関数・Hookが提供されることによって、関数コンポーネントでもいろいろなことができるようになりました。あと、ここで書かれていないもので言うと、useRefやuseCallbackなども使うことが多いです。

useStateの基本的な使い方です。useStateに初期値を渡して、配列の分割代入を使用して、stateとそれを更新するための関数を受け取って使用する、というような書き方が基本です。

ジェムクックのコンポーネントとHooksの歴史

ここからが本題のジェムクックのコンポーネントの歴史です。ジェムクックも、初期はクラスコンポーネントとビューを返すだけの、簡単な関数コンポーネントを使用していました。

ただ中期になると、Recomposeというライブラリが公開されたので、それを使用しました。クラスコンポーネントはもう使わず、関数コンポーネント+Recomposeです。そしてようやくHooksが登場して、関数コンポーネント+Hooksという構成になりました。

Recomposeの採用とつらいところ

Recomposeの採用について。Recomposeというのは、関数コンポーネントに今まで使えなかった状態の付与とか、ライフサイクルの実行などの機能を与えてくれるHOCのライブラリ。Hooks以前のHOCのライブラリですね。

このHOCは、コンポーネントを引数に渡してコンポーネントを返してくれる関数です。ちょっとややこしいですが、これによってクラスコンポーネントを排除できて、関数コンポーネントだけになりました。となったんですが、ただこれで「やったー」ということだけではなくて、Recomposeでもつらいところが、ちょっとだけありました。

Recomposeのつらいところなんですけど、RecomposeはHOCでコンポーネントをコンポーネントでラップするので、コンポーネントがどんどん増えていってソースが見づらくなってデバッグしにくくなったりっていうのがちょっとつらいなって思っていたところでした。

それとstateを定義するだけでも、HOCを使わないといけないので、ちょっと面倒くさいなんてことを思っていたところに、React Hooksが公開されました。

Hooks登場

Hooksの登場です。Hooksの導入によって、HOCが少なくなってシンプルな構成になりました。あとはuseContextとかでpropsのバケツリレーがなくなって……まあなくなったわけではないですけど、ちょっと減ってすごくシンプルな構成になりました。そしてカスタムフックを作成することで、コンポーネント内のロジックを再利用できるようになりました。

これからのHooksです。Hooks以前はクラスコンポーネントもHOCもコンポーネントを再利用して共通化するような手法だったんですけど、Hooksの登場によって、コンポーネント内のロジックをカスタムフックという単位で再利用できるようになりました。

今のライブラリの流れを見ていても、カスタムフックを提供するライブラリがすごく増えているので、これからもそれが主流になっていくんじゃないかと思います。

Hooks対応ライブラリ

ジェムクックでも使っているHooks対応のライブラリを紹介したいと思います。

react-useは、めちゃくちゃ便利なカスタムフックをいっぱい提供してくれるutilのライブラリです。GitHubにストーリーブックとかもあるので、眺めているだけでもけっこう楽しいライブラリなんですけど、ジェムクックでも多用しているというか、お世話になっています。

react-tableは、バージョン7以降からHooks対応したテーブルのライブラリです。実際自分で使ってみても、Hooks以前とHooks以降でもう書き方がまったく違うので、最初はちょっと面食らったんですけど、代わりにUIの構築にすごく集中できるようになったので、Hooksいいなぁと再認識したライブラリです。

そしてFormik。バージョン2以降からHooks対応したフォームのライブラリなんですけど、これもジェムクックでも使っています。あとここには書いていないんですけど、Redux Hook、React Routerとか、React Navigation。こちらはモバイルのReact Nativeのほうですね。これとかもHooks対応しています。ライブラリのHooks化は、これからもどんどん進んでいくんじゃないかなと思います。

これからの主流は「関数コンポーネント+Hooks」

今日のまとめです。Hooksの登場で関数コンポーネントが主流になりました。今まではクラスコンポーネントだとか、あるいはRecomposeでHOCで書くというような書き方でしたが、新しいプロジェクトとかこれからの主流は、関数コンポーネント+Hooksになっていきます。

Hooksを使用することで、コンポーネント間のロジックを共通化できるようになったのも1つ大きなところです。これまでは、ライブラリとかでもコンポーネントを提供するかたちだったんですけど、カスタムフックを提供するライブラリが主流になって、さらに柔軟なReactの書き方ができるようになっていくんじゃないかな、と思います。

ご視聴ありがとうございました。