Rのつく財団入り口

ITエンジニア関連の様々な話題を書いているはずのブログです。

【雑記】React Hooks+TypeScript周りをやってみたよ【JavaScript】

TypeScriptに入門+React周りに再入門の巻ですよ

 変化の大きいフロントエンド周辺。後発のVue.jsも日本では人気ですし、日本では商業本がReactよりVue.jsの方が手厚く出ているという面白い状況になっています。
 その一方、ダウンロード数でみると世界レベルで圧倒的に強いのはReact。世界レベルで使われているようなサービス、Facebookにインスタ、ネトフリなどなども軒並みReact。このはてなブログもReactが使われていますね。

 さて僕は2017-2018年頃からフロントエンド方面も入門を始めました。半分仕事で調べた結果をフレームワークの比較記事にしたらはてブで突然バズってびっくりしたりしました。

iwasiman.hatenablog.com

iwasiman.hatenablog.com

 今でも定期的にアクセスがあってありがとうございます……当時はまだまだ入門中だったので、本業のフロントエンドエンジニアの方々ほんまスンマセンという感じです。
 現在ここまでReactが強く支持されるにはそれだけ強い理由があるはずなのですが、その理由について自分的にはいまいち納得感をもった理解がしきれていませんでした。最近TypeScriptを学びつつReact周りに再入門してみたので、この記事はその記録です。

f:id:iwasiman:20210528191051p:plain
Galvjiというフォントで似せてますが公式ロゴとちょっと違います。Arial,Helvetica Neue,Verdanaでもけっこう近い。

学習に使ったもの

TypeScriptに関する商業本としてはオライリー本の『プログラミングTypeScript』が2020年発で最新です。

React本としては技術同人誌界隈で以前から絶大な評判を集めていた『りあクト!』シリーズを読んでいるのですが、噂通りこれはすごい。今後商業本になるとBOOTHのメッセージで聞いたのですが待ちきれずに3.1版をゲットしました。

oukayuka.booth.pm

会社でUdemy for Businessが使えるので、Udemyの講座は以下のあたりを見ました。倍速で見たり実際にコードを書いたり、応用っぽいところは流しちゃったり。終わらなかったものもあります。

Udemyは評価の高いもの、受講者数や評価者数が多いものを選べばまず間違いないですが、上のものでは上の4つ、講師がはむさんのとじゃけぇさんのが特にオススメです。

 自分の場合はできたものをGitHubに上げたら、LAPRASが検知して技術力スコアを上げてくださいました。ふふふ、どうぞワタシを優秀でイケてるフロントエンドエンジニアだと誤認してくださるがよいぞ……

f:id:iwasiman:20210528193103p:plain:w300
ちょこっとアップ

ほか、我が家のぬいぐるみ軍団を動的表示するという何の使い道もないかんたんReactアプリを前に作ったのですが、React HooksとTypeScript版で作り直してみたりしました。

f:id:iwasiman:20210528191535p:plain:w400
フレンズ検索アプリ。すっごくなーい!たのしー

github.com

やってみた

TypeScript やってみた
  • Udemyの講習だとコマンドのts-node, ts-node-dev で小さなコードを逐一実行して結果を確認できるのが分かりやすいです。
  • 書籍は『プログラミングTypeScript』が後半は難しいけど一式網羅していて役に立ちます。作者の方が熱烈なTS推しなんだなーというのがよく分かります。
  • 全体的にJavaScriptの危ない仕様とか地雷が埋まってそうなので避けようとなるあたりが、TSでは言語仕様でちゃんとしていて、あーこんな優等生になって……というような謎の感動の仕方をしました。クラスの書き方で普通のオブジェクト言語風にふつうにメンバ変数が書けたり、メソッドのスコープが定義できたりインターフェースも定義できるのも感動します。
  • まあサーバーサイド(バックエンド)をTypeScriptで書く機会は自分の場合はなさそうなので、あるとしたらフロントエンドでReactとなのですが、この強力な型推論やエラー表示のサポートだけでも十分役に立ちそうです。
  • TypeScript+VSCodeでの開発経験が圧倒的だ……というのはフロント界隈のいろんな方が言ってるのですが、実際に体感してみると確かにこれは快適ですね。同じMicrosoft謹製だからサポートが厚いのも納得ですが、ドットを打ったりCtrl+Spaceを打った時の補完表示が手厚い。初めて触ったプログラミング言語動的言語の世代で、初めてこの体験をしたような方は感動するのではないでしょうか。
  • 自分はもっと上の世代なのですが(笑)、EclipseなどでJavaを書いたりVisual StudioC#を書いたりした時、コンパイルエラーを潰して潰して潰して全部なくなってご安全にオッケイ、のあの感覚に似たものを感じました。これからスケールしてコード量が増えていくJavaScript大規模開発でも安心だなというのは何となく分かります。
  • そしてコーディング段階ではきっちり型でサポートして、トランスコンパイルされた後はマシン後に変換されるわけでもなく動的言語JavaScriptとして今まで通り動く。この発想もうまいこと考えたもんだな~と思います。

www.typescriptlang.org

React+TypeScript やってみた
  • UdemyのReact講座を、動画ではJavaScriptでやっているところを自分ではハードルを高めて最初からTypeScriptでやってみたり、いろいろ試しました。
  • TypeScriptにはいろいろ高度な仕様がありますが、簡単な関数コンポーネントを書くなら型を React.FunctionComponent 型にする、propstypeinterfaceで定義して中身に補完が利くようにする、useStateなどのHooks系も必要に応じジェネリクスで型指定、コンポーネント内の内部関数も必要に応じ引数や戻り値を明記、変数も型を明記……と、使うのはTypeScriptの基本的なところになるかと思います。これだけでも型推論やエラー表示のサポートだけで十分役に立ちますね。
  • JSXを変数に格納する時にしばしハマッたのですが型はJSX.Element型かReactElement型でした。(どちらがいいのでしょう)
  • あとイベントの型もまとめてSyntheticEventでやるやり方も、React.XxEvent<HTMXxElement>) で細分化するやり方もありました。
  • 最初はけっこうエラーが出るので、型でanyはダメ……anyを認めたら負けよ……と固い意志を持って潰していきましたw
  • Udemyの講座でCSS in JS系のライブラリをいくつか紹介してくれるコーナーがありました。講座ではJavaScriptでやっていてすんなり進むのですが、TypeScriptで同じことをすると動かないライブラリもあったりしました。まあ自分のスキルが足りないだけなのですが、完全にはTS対応しきってないライブラリがまだまだあったりはしそうですね。
  • Reactで新規プロジェクトを作るならもうJavaScriptでなくTypeScriptで行こう……というのが最近のトレンドとして盛り上がっていますが、実際にやってみてそう思いました。今はボイラープレートのCreate React App もだいぶ進歩して
    create-react-app appname --template typescript からプロジェクトを作ればJavaScriptほぼと同じ感覚で始められますし、だいぶ敷居も低くなってきたのかなと。
  • このTypeScriptとの親和性の高さもReactが伸びた要因のひとつとして上げられますが、それが体感できました。この点で後れを取っていたVue.jsも2020年秋のV3から遂にTypeScript対応を強化しましたが、さあこちらはどこまで伸びるでしょう。

ja.reactjs.org

React再入門してみた
  • 本を何冊か読んだり試しに作ったりはしてきたのですが改めてということで。最新の商業本が不足しているReactですが、Udemyの講座だともう関数コンポーネントが基本、状態管理周りもReact Hooksで……という公式最新のスタイルで学ぶことができます。
  • JSで関数と言えば function hoge(foo) { ... } というオールドスタイルが染みついてしまったワタクシは
    const fn = (in: string): string => {} みたいなアロー関数記法がなかなか慣れなかったのですが、Reactだと特にこれを多用しますね。やってくとだんだんこれが自然に思えてくるので、まあこのへんも結局慣れなのかなあと。
  • スプレッド構文による分配など、モダンなJSの書き方もReactでは積極的に活用しているので、俺は今新しいJSを書いている! みたいなフロントエンドやってる感、全能感的なモノを味わうことができます。
  • React界隈のライブラリの変遷なども見てみるとJavaScript自体の高度なパワーをふんだんに使っていて、やっぱりこのへんはJavaScriptに強い人、(良い方の意味での)意識の高いエンジニアに支持されてきた玄人JSer向けフレームワークなんだなという印象を改めて受けました。

  • タグに相当する部分を書く時のあのJSX、「JSXキモい」まではいきませんが自分も最初は抵抗を感じました(笑)。
    return文を囲う( )、タグの< >、この範囲はReact側のJavaScriptの世界であることを示す { }、アロー関数の () => {} なんかが混ざって何やら最初は黒魔術的に見えるんですよね。初心者が挫折しがちというのも分かります。これもいろいろ試行錯誤したりリファクタリングしたり、書いていくうちに体感的にだんだん分かって慣れてくるので、やはり慣れなのかなと。

  • 一覧表示などに使う繰り返しも、HTMLテンプレート形式を使っているVue.jsのタグの中に書くディレクティブ方式の方が一見すると分かりやすく、Reactでのmap関数の中に書いていくやり方は最初は「ん?」となりがちです。
  • でもこれも書いていくうちに慣れてきますし、思想としてJavaScript/TypeScriptの構文が書ける世界の中で、JavaScript自体の力を活用してやっていく方向なんだなあというのがだんだん分かってきます。
  • このあたりは技術同人誌『りあクト!』に深いところまで解説してあってとても面白いです。

oukayuka.booth.pm

qiita.com

  • といっても一方的にJSXこそ至高!HTMLテンプレート形式はクソ!ではなくて、一枚絵のHTMLに近い構造だったらAngularとVue.jsが採用しているHTMLテンプレート形式のほうが理解しやすいですし、HTMLとCSSしか分からない人にも見てなんとなくわかるでしょう。
  • このへんは技術の話によくある二項対立の話で、常に片方が良くて片方はダメということではなし。実際には開発メンバーのスキルや好み、作ろうとするアプリケーションの複雑さ、フロントエンドエンジニアがデザインもやるのかそれともデザインOnly寄りの人がどれだけ関わるのか、などなど、そのプロジェクトの背景情報をもとに決定していくところかと思います。
React Hooksやってみた
  • 正式機能として2019年に導入、React界では革命的な変化として知られるHooks。商業本だとまだあまり扱われていないのでWebの情報頼りですが上述のようにUdemyの講座や、技術同人誌『りあクト!』だと詳しいです。
  • 昔は状態が持てないはずだった関数コンポーネントでも useStateを使うと状態が持てる。たとえばuserIdを持ったクラスコンポーネントだったら this.state.userId なのが、関数コンポーネントconst [userId, setUserId] = useState(null)を使うとconstな変数に入るから userId で済む。
  • こういう話をネットの記事で見た時は「はーん。で?」という感じだったのですが、実際にやってみるとこれがとてもスッキリに感じられます。JavaScriptの鬼門thisを見なくてスッキリ、ドットを書かなくてスッキリ、思考がスッキリです。シンプルにstateが入った変数やsetXxx関数が入った変数を子供のコンポーネントに渡していけばいいのでコードも簡潔になります。
  • useEffectも最初は「副作用」という言葉に戸惑うのですが、コンポーネント読み込み時、更新時、終了時……など時間的なタイミングごとにすべてのデータについて書かなくてよくなり、データの種類ごとにコードを集中させられる……というのが分かってくると確かにこれはコードの見やすさ上も進歩ですね。
  • useReducerなど高度な機能はまだ理解しきれていないのですが、確かにこのHooks周りは大改革だなというのが分かりました。
  • かつては React+Redux のようにほとんどReact本体同様にセット扱われていた状態管理のライブラリRedux。よくFluxアーキテクチャの図もネットでは解説されましたし、若干ドヤ気味に紹介されたりもしました。しかしこのReduxも入門する側から見ると「この技術ほんとにいるの?よけいに難しくなってない?」という感じは若干ありました。
  • React HooksのuseStateuseContextなどを活用していくと状態をコンポーネントの外側で持てるので、あれ、もしかしてReduxは今後いらない子になっていくなるのでは……という気がだんだんしてきます。このへんの話も技術同人誌『りあクト!』の中が面白いのですが、どんどん進化していくのだなあと思いました。

ja.reactjs.org

コンポーネント分割やってみた
  • アプリケーションが大規模になっていくとこのへんのコンポーネント分割、状態の持ち方のあたりの設計が肝なのだなというのがサーバーサイドをじっくりやった身からしても分かります。Udemyの講座ではその場でリファクタしてコンポーネントを分けて行ったり、Atomic Designに従って小さなコンポーネントを作っていったりで学ぶことができます。
  • 粒度が細かくなって小さな描画するだけのコンポーネントになると、親コンポーネントのJSX部分の中を抜き出して新規作成の子供コンポーネントの戻り値に書いていくだけになったりします。リファクタリングはけっこう素早く、直感的にやっていくことができました。このへんやはりよくできていますね。
  • 使い回しができるボタンを作ったり、動きやデータは外側から渡したり、JSXの囲みタグの外側でライブラリを呼べたり、{children} と書くだけで子要素に適用されたり...。JSXベースでコンポーネントを書いていくReactの思想はやはりしっかりできているのだなあというのがだんだん体感できてきました。
  • コンポ―ネントの粒度が細かく小さくなってくると、ほとんど描画するだけのシンプルなコンポーネントができてきます。
    ロジックと見た目の分割というのも関係なくなってくるし、CSSの指定がすぐそばのJSコード内にあっても気にならなくなってきます。なるほどJavaScriptの世界の中でタグのレンダリング部分も書いちゃうというJSXの思想、ロジックと見た目は無理に分けずにコンポーネントの中に閉じ込めるReactの思想はこのへんで効いてくるのが分かります。
  • 実際にいろいろ試してみると、Atomic Designの思想に大まかに基づいたりして、できるだけ粒度を細かく小さくしたコンポーネント構成に向いているのはやはりReact。Vue.jsに向いているコンポーネントの粒度はもう少し大きいのかな……?という気が若干してきました。

qiita.com

qiita.com

zenn.dev

自分は手軽に使えるVue.jsもけっこう好きなのですが、本格的に始めるにはReact+TypeScriptも熱いですね。

小~中規模で完結する予定で手軽に開始したい、CDN経由やビルドシステム導入しないなどライトな利用、メンバーの学習にコストを掛けられない、HTML/CSSは分かってプログラミングは強くないデザイナー寄りの人と協業が必要……等の場合はVue.js。

一方、最初は小さくスタートでも今後 src/components/ 配下に粒度の細かいコンポーネントがバンバン増えていきそう、エンジニアの数も増員予定、アプリもスケールしてどんどん大きくなる……などのプロジェクトでは初期コストがかかってもReactを採用。途中でなく最初からTypeScriptを導入してがっちり型でガード。これから新規開発するなら関数コンポーネントとReact Hooks使用で統一。コンポーネント構成や開発ルールも定めつつ品質に目を配りながら、大きく育てていく……

もちろん逆も可だし一概に言えないのですが、大まかにはこういう感じの使い分けなのかなと思います。
いやはや、こういう正解のない世界は面白い。ということでReact力が若干高まった(ような気のするw)最近でした。

f:id:iwasiman:20210528191051p:plain
原子構造らしい?Reactアイコンもかっこいいですね