Rのつく財団入り口

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

【感想】『りあクト! TypeScriptで始めるつらくないReact開発 第3.1版』【Ⅲ. React応用編】: #りあクト でよりディープにReact入門

りあクト!

 技術同人誌のりあクト!、【Ⅲ. React応用編】の読書記録と感想です。

oukayuka.booth.pm

【Ⅲ. React応用編】

 大変革であるReact Hooks登場を受けて第3部では副作用処理をテーマとし、公式でもこれからリリースでまだ実験的な機能のSuspenseを扱った応用編の話となっています。

f:id:iwasiman:20210618135306p:plain
りあクト!【Ⅲ. React応用編】

第10章 React におけるルーティング

 10-1. SPA におけるルーティングとは

  • サーバーサイドの仕組みであるRailsを対比に挙げながら改めてSPAとルーティングについて。DOMの動的な書き換えによってページ遷移を疑似的に実現すると共に、「ブラウザのセッション履歴をそれに同期させること」。

 10-2. ルーティングライブラリの選定

  • React Router がデフォルトかと思っていたら、確かにそうなのですが2番手の Reach Routerも勢いがあるとのこと。実は両方とも作者が一部被っていたり同じ会社のプロダクトだったり経緯が存在。React Routerのバージョン6は Reach Router を統合してひとつになるがここで破壊的な変更となり、バージョン4や5は動かなるとのこと。(!)
  • 過去にもこういうバッサリと後方互換性を切り捨てる変更はあったそうで、このへんの経緯も語られているのがありがたいです。
  • バージョン6は2021年夏ごろ出る見通しで新機能のSuspenseとの親和性の話もあり、これからは推奨は6系現在は5系を学びつつ6系への移行も知っておくのが安全とのこと。
    こういうところはフロントエンド周辺はやっかいでありつつも、変化に追随するためには仕方ないところですね。

reactrouter.com

 10-3. React Router(5 系)の API

  • 自分はUdemyでも学んだのですが、インストール方法、JSXのトップに<BrowserRouter>を書き、分岐部分で<Switch>-<Route>-中のコンポーネント... という形で呼ぶ方法などが解説されています。
  • 5系でも最新バージョンはAPIもHooks形式になっているんですね。
    • useHistory : 独自定義のhistoryオブジェクトを返し、履歴情報と移動のメソッド
    • useLocation : locationオブジェクトにpathnameやパラメータなどが入っている
    • useRouteMatch : matchオブジェクトにパスやURL、isExact、params
    • useParams : matchオブジェクトの中のURLパラメータだけをシンプルに返す

 10-4. React Router をアプリケーションで使う

  • おなじみ『SLAM DUNK』の面々一覧表示アプリを例に、v5で丁寧にコード例を示しています。
  • container componentsrc/containers/ 、見た目用のpresentional componentsrc/components にまず2分割、双方で中でさらにAtomic Designの分け方で分割しています。人物データのPure TSファイルは src/data の下でした。コンポーネント構造の流儀は色々あると思いますが、こういうやり方もあるんですね。
  • HTMLの<title>をどのコンポーネントからでも変えられるというSPA用のライブラリ React Helmet 、詳細を初めて知りました……
  • コンポーネント移動時にスクロールバーが上に戻るように、トップのAppコンポーネントwindows.scrollTo(0, 0) を使うというテクニックも何気に初めて知ったような……(このへん、商業の入門書でも書いてなかったりしそうです)

www.npmjs.com

 10-5. React Router バージョン 5 から 6 への移行

  • React Router 自体もTypeScriptで書きなおされたというv6の変更点をまとめ、前節で登場したスラダンの表示アプリをv6対応に書きなおす実例を挙げて移行を説明しています。既に現場で使っている方にはありがたいでしょう。
  • 本書では、v6で仕様が変わりデメリットはあるがメリットの方が大きいので、新規プロジェクトでは安定版リリースがもうすぐのv6を最初から採用したほうがよいとのことです。

第11章 Redux でグローバルな状態を扱う

 11-1. Redux の歴史

  • 最初は勉強になる歴史的経緯から。model-view双方向のデータのやり取りが多くなると大規模なアプリでは複雑さが増し破綻してしまう。AngularJSなどの第2世代のフレームワークはこれで失敗。フロントエンドに限ってはMVCアーキテクチャは役に立たない。
  • そこで……と2014年にFluxというアーキテクチャパターンが登場します。
  • そしてReduxライブラリの開発者でもあるOSS開発者が1週間ぐらいで作ったのが発表されて世界に衝撃、9-1に出てきたHOCの有力ライブラリRecomposeの作者だった別の人が感動して自作ライブラリを捨ててこのReduxに協力、2人とも結局Facebookに招かれてReact自体の開発にジョインした……という裏話も面白い。
  • 本書でもツッコまれてますが、Facebook本体が作ったライブラリより外部のものが優秀で結局後から本体に取り込まれる、というパターンが多いのですね。

 11-2. Redux の使い方

  • よくネットの記事にも出てきますが思想について。

    • 信頼できる唯一の情報源:Reduxではシングルツリーの1つのstore限定でデータを保存。
    • 状態は読み取り専用:stateは直接変更不可、変更依頼はaction発行に集約。
    • 変更は純粋関数で:reducer引数が(前のstate, アクション) => {新しいstateを返す}
  • reducerは確かに英語の「減らす」ですが本書によると「還元する」「減数分裂する」の意味の方のニュアンス。reducerFluxを掛け合わせたからReduxというネタも初めて知りました……!

  • そして実例はカラフルなカラービーンをカウントアップしていくもの。ネットでもよくサンプルコードは見かけますが、2019/6にReduxにもリリースされたHooks APIを使って完全にTypeScriptで書いています。結構違いますね……
  • そして作中では百合イベ……じゃなかった親密度向上イベントが発生して先へ。このとき柴埼先輩はどんな表情だったのか、私気になります! コミカライズかアニメ化で映像化はよ……

 11-3. Redux 公式スタイルガイド

  • 存在を知らなかったのですが、Reduxを書いていく際に全て必須ではないが守ると良いとされているガイドの17項目ほどについて詳細に解説されています。
  • actionのタイプ名は「ドメインモデル/イベント種別」のフォーマットが良い(type: 'user/setName'など)なんてのは初めて知りました。ネット上のサンプルもアッパースネークが多いような……?
  • フォームの状態をReduxに入れないというガイドがあるけど入れている有名ライブラリもあったりしたそうで、やっぱりこのへん設計の考え方でも紆余曲折があるのだなあと思います。
  • フォーム関係のライブラリではトップがFormik、追随しているのがReact Hook Formとのこと。

qiita.com redux.js.org

 11-4. Redux Toolkit を使って楽をしよう

  • 2018年当初はRedux Starter Kit、2019/12から名前も変わってRedux Toolkitとなった、Create React AppのようにReduxを使う際のコード記述を楽にするライブラリの話。
  • コードの実例は正直難しく見えるのですが、記述がよりシンプルになっています。

 11-5. Redux と useReducer

  • Reduxは状態をグローバルで管理していたが、React HooksのuseReducerはこれを個別のコンポーネントレベルで可能にするAPIだということで前節のアプリを書きなおしています。
  • そして、HooksのuseStateは実はsetter actionがひとつしかないuseReducerであり、中の仕組みは同じ、限定版のような機能である……!ということで、React内部の秘密を解き明かす感じで図を用いながらディープな解説が。こういう話もありがたいです。
  • 文中でもこのあたりがReactの中で特に難しいとあるのですが、同じ感想を持ちました。確かに分かったようなまだまだ不十分なような……

第12章 React は非同期処理とどう戦ってきたか

 React本体は一応UIに特化しているので、外部のRESTなAPIと通信したりはコンポーネントの中から実施。だが複雑なアプリになるとどんどん難しくなるので、コンポ―ネントの外側で非同期通信やデータ保持などの処理を行う方法が編み出されました。その変遷をたどる章。

 12-1. 過ぎ去りし Redux ミドルウェアの時代

有名なReduxには最初からミドルウェア(middleware)という仕組みが用意されており、一連の流れの途中に処理を挟むことができる良い設計になっていた。このミドルウェアのライブラリも流行った。ここでも御三家あり。

最大手Redux Thunk
Redux公式の謹製。thunkコンピュータサイエンスの用語で、計算の遅延評価の際に引き渡される計算の実体のこと。(感謝のThanksをもじったのかとアホな連想をしてました……笑)
Dispatcherに渡すActionの中にthunkも一緒に渡して高度な処理。一見簡単そうに見えるがコールバック地獄に陥ったり難しい。そもそもRedux本体の在り方から離れている。

redux-saga
Reduxのデータフローの外側にsagaの部分が入る。ロゴがこの形になっている。タスクをsagaが監視して処理を挟み込むような感じ。マイクロサービスで分散トランザクションを実現するためのsagaパターンと関連。JavaScriptの高等機能のジェネレーターやyieldを使い、難しい。

サーバーサイドのPHPフレームワーク Laravel でも、HTTPリクエストが飛んできてController層が動いて返るまでの間に共通処理を挟み込んだりできる機能が同名の「ミドルウェア」となっていますね。
sagaについては書籍『マイクロサービスパターン』でも、パターンのひとつとして難しいですが詳しく解説されています。こういうところが繋がっていくのが面白いです。

iwasiman.hatenablog.com

 12-2. Effect Hook で非同期処理

  • これらのミドルウェアを使う方法は学習コストが高かったり、コード量が増えて分離ができなかったり、テストしにくかったりで難しかった。
  • 解決するためのライブラリも考えられた余計に難しくなったりで根本的に解決せず。(このへんが初心者がReactを敬遠する流れ、ライト層がVue.jsに流れた原因では……というパイセンの分析が面白いです。)
  • そこでついに公式React神が降臨、React HooksのEffect Hookが登場。関数コンポーネント内でもuseEffect()を使えば async/await を使って非同期通信などの処理を挟める。Custom Hookを使って別関数に切り出すとさらに綺麗なコードになる。
  • コンポーネント間でデータを共有する時はReduxの一部だけ、useDispatchuseSelecter を使うと実現できる。

 12-3. 「Redux 不要論」を検証する

  • Reduxの作者 Dan Abramov さん自身が2016年に悲しみとともに脱退、2018/3公式リリースのContext API(New Context API) がバケツリレー問題を解決するもまだ使い勝手悪し。
  • そして2019年のReact Hooks登場でHooks API形式のuseContext() が使えるようになり、ここでようやく解決。
  • NameContext = createContext('name'); したら <NameContext.Provider value={useStateで作った変数名} >のようなJSXで子孫を囲うと、子孫の側でもuseContext() 経由で値を受け取れる。コールバック関数も一緒に渡せば子孫の側からも更新できる。これでだいたいReduxが代用可能。
  • ブラウザ上でもコンポーネント群で別々の技術で動くようにする「マイクロフロントエンド」という夢の概念、BackEnd for Frontend(BFF) の技術群などなどが登場。データは中央集権の一元管理というReduxの考え方と逆に向かっている。
  • また2020年、Facebook謹製の状態管理ライブラリRecoilが登場。しかしReact公式のライブラリではない。

 本書の柴埼先輩の意見では、今後ECサイトSNSレベルの普通のReactアプリ開発ではReduxの必要性は低下。しかし必要になるケースもあり、モバイルやデスクトップアプリではまだまだ必要では、とのことでした。

 いやはや歴史を踏まえた解説は面白くもあり、難しくもありました。(12-2ではHooksのuseEffectに加えてReduxもちょっとだけ使ってデータ共有を実現共有していましたが、12-3のuseContextuseStateを使えばもうHooksだけで完結するのかな??)

 React Hooks登場に加えてさらにFB謹製の Recoil が登場してこれがReduxキラーの決定打なのか?!と思ったらそういう訳でもなさそうだし、こうしてReduxの使用は徐々に減ってきたのです……というストーリーを予想しつつダウンロード数のグラフを見たら今でもReduxが圧倒的トップだったり、なかなか混迷しているというかピシッと決まらないものですね。
 早期からReactを導入して大規模なアプリケーションにReduxを活用している会社さんは、今後が悩みどころなのだろうなあと想像しました。

第13章 Suspense でデータ取得の宣言的 UI を実現する

 13-1. Suspense とは何か

  • Hooks登場で万事解決かと思いきや、無限ループが起こりやすいのと宣言的でないという問題あり。React公式チームが実験的な機能を水面下で用意しつつあるという話。
  • Suspense for Code Splitting :コード分割のためのSuspenseコンポーネントを使うその時までロードを遅らせる遅延ロードの機能がReact16.6で登場。この時のSuspenseという機能が非同期なデータの取得にも使える。
  • JSXのトップを<Suspense>で囲う形式。こうすると宣言的UIで書けるが、リソースを生成する部分の書き方が不思議になる。

 13-2. “Suspense Ready”なデータ取得ライブラリ

  • Suspenseの機能についての主要ライブラリ側の対応が2019年末あたりから開始。Facebook自体の画面もRelayというライブラリを使用。しかしまだ万人向けではない。
  • GraphQLApolloがDL数では圧倒的。しかしSuspense対応は保留中。
  • urql(Universal React Query Library) という最近伸びてきたライブラリがSuspense対応で進んでおり、柴埼パイセンのお勧め。
  • データをfetchし、キャッシュ機能もあるライブラリではSWRReact Queryの2択。
  • SWR: Stale-While-Revalidate、HTTPヘッダの名前から。Next.jsやフロントエンド用PaaSであるVercelの開発元Vercel社で安心。APIも少なく分かりやすい。2019/10に登場。
  • React Query: 個人開発のライブラリだが開発速度が圧倒的、機能も豊富で破壊的進化中。Chrome拡張で専用のDev Toolもある。最近DL数でSWRを抜いた。
  • React QuerySuspsnseを使うサンプルコードあり。

 ここまで来ると高度過ぎてよく分かりませんでした……! Suspenseが本書にあるようにReactの変態的な、もといとても高度なところを使っているのは分かったのですが、いやはや難しい。Suspenseを使ってすら無限ループの呪いからは逃げられないと聞くと、じゃあどうしたらいいのじゃ~となります。

小ネタとしてはHTTP通信のライブラリでよく聞くaxiosは内部でJavaScriptの新しいfetch関数を使っていないので、fetchを拡張したkyというライブラリが今は良いそうですね。こういう話もありがたいです。

 13-3. Suspense の 優位性と Concurrentモード

  • Webページ表示までの方法に3通りのアプローチ。Fetch-in-Render, Fetch-then-Reder, そしてSuspenseを使ったRender-as-You-Fetch。フェッチすると自動でレンダリングも一緒に始まり、結果として応答性がよくなる。
  • また複数の問い合わせが非同期で始まると時系列で帰ってきた順にstateが更新されてしまうRace Conditions(「競合状態」)の動作も、Suspenseを使うと勝手に解決してくれる。
  • そしてReact本体が数年前からずっと進めているConcurrentモード。レンダリングを中断して他の処理を優先させるようなスケジューリングができるようになり、Suspenseと組み合わせると効果大。2020/10のv17ではまだ盛り込まれず。

 13-4. Suspense と Concurrent モードが革新する UX

  • Reactの思想には開発者体験(DX)の重視がずっとあったが、ユーザー体験のUXファースト重視の考えが最近登場。
  • コードを変えなければいけませんが、実験的なConcurrentモードを有効にする方法、API群、そして「Concurrent UI パターン」を使った検索画面の実装例も解説されています。
  • 最後のSuspenseConcurrent モードは非同期処理の最終解か?という話では、まだFacebook以外は使っていないし実験的な機能だが、Reactが長年構想してきた大きな革新であり早めに採用しよう…となっています。次のv18で正式に登場するらしいですね。
  • そして最後のエピローグでは、好感度上昇によるパイセンとのサシ飲みイベント発生。二人の仲も深まって3冊に渡るReactのディープな入門は完了するのでした。

まとめ:IIIでさらにディープにReactの神髄に触れられる本

 IIIは応用編ということでさらに難しく深いところを解説し、サンプルコードのお遊びネタもスラムダンク以外おとなしくなってしまうほどディープです。フロントエンド強者でない自分も正直理解しきれませんでした。(笑)
 主要ライブラリの変遷など裏話も面白くありつつ、難しいことを別の技術で解決しようとしてさらに難しくなっているような感じも受けます。Reactの本質の基礎部分はしっかり落ち着きつつも、やはり高度な領域はまだまだ変化を続け定まっていないのだなあと思いました。

 ということでI~IIIまで3冊、Reactを巡る長い旅も終了。評判通り、技術同人誌と思えないほどのクォリティでした。これで3冊3600円というとかなり良コスパですね。
 ~IIIまで理解できていれば本書の柴埼先輩のようにテックリードクラスでイケちゃうでしょうし、I~IIまでの理解でも仕事レベルの開発で十分通用すると思います。
本書の狙い通り技術の背景がきちんと解説されているのが偉いですし、読んでいてそういう小話がとても面白い。
主要ライブラリの動静などを普段からしっかり押さえてきた、長年React愛を持った方の想いが柴埼パイセンの立場から注ぎ込まれた本なのだなあと思います。
 欠点は別にないのですがReact推しの立場からの技術同人誌なので、他のフロントエンドフレームワークの描写あたりはなかなか主張が強く批判的ですね。こういうところはひとつの立場からのオピニオンだということで、そういうものだと思って読めばよろしいでしょう。

 このエントリの下書きを書いていた2021年7月現在、新しめのReact商業本というと『React.js&Next.js超入門』の2版、電子のみの『速習 React』ぐらいしかありません。(React.js&Next.js超入門 第2版速習 React 速習シリーズ) (追記:8月にオライリー本で1冊出ています)

これらの商業本を差し置いて仕事で使うレベルの深い本であればまずこの「りあクト!」を、となれる、事実上最強のReact本でした。boothからの以前のメッセージで拝見したのですが商業本となるご予定もあるようです。

 そういえば読み手を代弁する立場の作中の秋谷香苗さんは、作中の時間経過で本当にたった1週間でこの3冊分を先輩から教わって学びきっているのでしょうか。だとしたらエンジニア新卒2年目にしては超優秀、これ1ヶ月の間違いじゃないかという気がします! いや2年目のワイだったら1ヶ月でもムリかも......w

f:id:iwasiman:20210618135306p:plain
りあクト!【Ⅲ. React応用編】

なお本書に登場する柴埼先輩と秋谷さんの世代設定の謎ですが、記事公開時に作者さん自らからご反応いただきました。
やっぱりちゃんと設定があった~! ということで貴重な裏設定Getを記念してここに引用させていただきます。(笑)

関係書籍など

本書のサンプルコードのリポジトリgithub.com

頒布時のtogetterまとめ。 togetter.com

りあクト! TypeScriptで始めるつらくないReact開発 第3.1版【Ⅰ. 言語・環境編】 oukayuka.booth.pm りあクト! TypeScriptで始めるつらくないReact開発 第3.1版【Ⅱ. React基礎編】 oukayuka.booth.pm りあクト! TypeScriptで始めるつらくないReact開発 第3.1版【Ⅲ. React応用編】 oukayuka.booth.pm

りあクト! TypeScriptで極める現場のReact開発 booth.pm りあクト! Firebaseで始めるサーバーレスReact開発 booth.pm

Reactをはじめとするフロントエンドフレームワークの入門本まとめ記事最新版が、このブログ内のこちらにあります。

iwasiman.hatenablog.com