この広告は、90日以上更新していないブログに表示しています。
技術同人誌のりあクト!、【Ⅱ. React基礎編】の読書記録と感想です。

5-1. なぜ React は JSX を使うのか
表面的には「JSXキモい」とか言われがちでもあるこのあたりの本質が、本章でしっかり解説されています。
JSX の本質を理解する:
Rails思想が根本にある秋谷さんはERB(Embedded Ruby)のようなテンプレート言語を連想するが、これは誤り。JSXはTypeScript的にはReact専用の型のオブジェクトを作るための式で、「JavScriptの拡張リテラル」が近い。だから変数に入れたり関数に渡したり様々な操作ができる。
なぜ見た目とロジックを混在させるのか:
伝統的なMVCアーキテクチャでの関心の分離は、「技術」の役割でレイヤーを分けている。しかしフロントエンドで適切なのは「機能」での分離なのが徐々に分かり、機能単位で分割された細かなコンポーネントでそれぞれの仕事をするスタイルがReactの設計思想になった。ゆえに、ひとつの小さなコンポーネント内でロジックとレンダリングを無理やり分割すると非効率になるというのがReactの考え。
なぜ React はテンプレートを使わないのか:
HTMLテンプレート派がAngular,Vue.js。ReactはあくまでJavaScriptの純粋な式で解決しており、JSファースト派。HTMLに固執せず単にブラウザが今回のプラットフォームなだけで、一貫した言語で開発する。
なぜ React は View をタグツリーで表現するのか:
React DOMがHTMLのレンダリング担当。スマホアプリ向けの有名なReact Nativeを始めレンダラーはほかにもいろいろ開発が続いており、JSXは最初から様々な用途を見据えて汎用的に考えていたから。 自分はフロントエンドに入門してからAngular/React/Vue.jsとも本を読んだり実際に作ってみたり色々してきましたが、現在の知識からすると本章の説明がなるほど……!と腑に落ちました。
JSXでの({({ みたいになる独特の書き方は最初黒魔術に見えるのですが慣れてくるとまあ書けるようになるし、言われてみるとテンプレートがない分Reactは実はディレクティブの書き方とか独自ルールは少ないし、JavaScript自体のパワーを活かすコードになります。前に試しに作ってみた時もReactだとコンポーネントを分割していくリファクタリングはけっこうスッと行けるんですよね……なるほどなるほど。
Vue.jsが特徴として掲げているProgressive Frameworkの思想をパイセンが「物は言いようだよね」と評していたり、おっこれは宗教戦争勃発不可避!?的なところもあります。本書の作者さんはReact推進派ですのでそれを踏まえつつ読む必要がありますが、それを差し引いてもReactの本質に迫った、非常に役立つ章でした。Qiitaにもこの話が載っています。
5-2. JSX の書き方
tsconfig.jsonがデフォルトのままならコードのimport React from 'react'; は実は省略してよいとのこと。これは全く知りませんでした……!null, undefined, true, false は出力なしになる。なので&&演算子のショートサーキットや三項演算子を表示表示の切り替えによく使う……と順序だてて説明してくれてありがたい。Propsに定義されていない値が渡ると暗黙のpropsとして扱われる話も知りませんでした……!interfaceとして定義されて処理してされていく話も仕組みを交えながら解説されています。checked, disabled, selected はReactでは文字列型でなくBoolean型として扱われるのもちゃんとは知りませんでした。textareaとselectもvalue属性を持てるのも知らなかった……!6-1. ESLint
JSLintという最初のツールを作成。JSHint→ESLint→JSCS→TypeScript用には一度TSLintが作られたが非推奨になってESLintに統合→現在はこのESLintの一強、という歴史的経緯の話もしてくれるのがありがたい。AngularはまだTSLintからESLintに完全に移行できていないのですね。.eslintrc.jsをコマンドから作成、ルールをカスタマイズ、関連するプラグインをインストール……でかなりしっかり設定していく方法が解説されています。大規模なチームの開発標準策定には大きな助けになることでしょう。6-2. Prettier
Prettier。こちらも誕生当時からReactのJSX変換機能と縁があり、他の言語までカバーを広げてフロントエンド全般を網羅するようになった...という歴史的経緯も解説されていてありがたい。eslint-config-prettierをインストール、設定ファイルeslintrc.jsを変更、package.jsonに設定追加してコマンドから実行できるように、VSCodeの設定settings.jsonも変えて……とコード保存時に一括整形する方法がかなり細かく解説されています。6-3. stylelint
stylelintの設定方法。これは存在自体を知りませんでした。6-4. さらに進んだ設定
7-1. React 登場前夜
prototype.js、2006年のjQuery、2008年のHTML5ドラフト公開、かつては一世を風靡したFLASHも2011年開発中止。ECMAScript仕様のES5が2009年。Backbone.js,Knockout,AngualarJS(バージョン1のほう)で当時3大フレームワークと呼ばれていたんですね。KnockoutがM-V-VMアーキテクチャを使っていて実はVue.jsの先祖にあたるという話も面白い。Angularが名前も変えて後方互換性を捨ててアーキテクチャも全面入れ替えしたのは有名な話ですが、大規模SPAでの性能的な限界が主だった……という話も詳しく載っています。そして2013年にいよいよReact登場。7-2. Web Components が夢見たもの
Web Componentの考えの話。良い構想だったもののブラウザベンダー同士の合意などで難航して結局主要ブラウザ実装が2018年頃とかなり時間がかかってしまった。7-3. React の誕生
FBoltという名前だったけど同僚とネーミングを相談してReactになったという裏話が面白い。Hackという言語を使っているという話は、FBが有名になったころよく聞きました。PHPでもHackでも両方使えるのでしょうか、コード内でXMLを書けるXHPという内部向けフレームワークがあり、これをJS版にしたものが実はJSXのネーミングの元になったという話も面白い。7-4. React を読み解く 6 つのキーワード
トップに3つ掲げられてきたキーワードも不変でなく実は入れ替わりがあるという話自体が面白いですが、それぞれを深掘りしています。
Declarative(宣言的):
関数型プログラミングとも繋がる、最終的な出力や状態をHTMLに宣言しておけば中のデータ変更はReactが上手くやってくれるスタイル。
構想段階から関数型プログラミング指向があったがReact最初はクラスコンポーネントしかなかったため一旦はキーワードから取下げられ、関数コンポーネントが追いついてきてから復活した模様。
Component-Based、Just The UI(コンポーネントベースでUIしかない):
過去のフロントエンド史での様々な挑戦から、MVCをそのまま持ってくるのは良い設計でないのが分かったため。MVCアーキテクチャでいうとVだけしか扱わない。Controller層やModel層に当たるものはない。
またUIだけで状態管理や様々な機能は外出しにしている。Facebook製のライブラリは敗れて、ReduxやTypeScriptなどFacebook外で作られた技術がデファクトになって取り込まれたりした経緯が、実はReactを強くしていった理由になっている。
Virtual DOM(仮想DOM):
各FWの中で様々なアイデアが試行錯誤されてきたが、メモリ上で差分だけ更新していく仮想DOMの考えが画期的だった。なお単純なレンダリングの速度だけの話ではなく、独自技術で進んでいるAngularも今はパフォーマンスはほぼ同等になっている。
One-Way Dataflow(単方向データフロー):
制御ロジックの値<->view上の値が同時に反映される「双方向データバインディング」は直感的でもあり多くのFWで採用された。しかし親子コンポーネントを大量に使う複雑化した大規模なSPAではこれが逆に問題になると考え、Reatは単方向データフローを採用。
常に親から子へpropsが流れていく。コード量は増えるがコンポーネントの独立性が保て、またReactの当初の構想からある関数型プログラミング指向とマッチ。
Learn Once, Write Anywhere (一度習えばどんなプラットフォームでも開発できる):
React本体と分離されているレンダラー部分はブラウザで動かす仮想DOMならreact-domだが、他のプラットフォームにも差し替え可能。モバイル開発のReact Nativeが代表。これらでもReactの知識が活かせる。同種ではAngularをベースにしたIonic Frameworkがあるが勢いでは負けている。またReact NativeのVue.js版であったWeexは開発が止まってしまった。
本書ではモバイル開発もReact Nativeが一番よ!的な記述になっていますが、2021年現在ではGoogle発のFlutterもいよいよv2が出て勢いを増していますね。
また、この"Learn Once, Write Anywhere "キャッチフレーズがJavaの"Write once, run anywhere"のもじりであるのは有名な小噺ですが、作中の秋谷さんがこれを知らないのに世代の差を感じました……(Java世代おぢさんの悲しみw
7-5. 他のフレームワークとの比較
第3世代のフレームワーク情勢としては、主要な3つの後のものに技術的な目新しい革新はないとして、Ember.js、Preact、LitElement、Svelteが登場しています。
Angular:
v2の大幅刷新で多くのユーザー離反を招いてしまった。フルスタックなのでコンポーネントを作るのも色々大変。実装もTypeScriptだが、特定バージョンに固定されてしまっていたりする。公式が提供するものを使えばよいので頻繁な変化に追随しなくてよい安心感はある。保守性も高い。
Vue.js:
ネーミングはviewのフランス語のvueから。(これは知りませんでした!)
Angularを使っていたGoogleエンジニアのEvan Youさんが不満点を感じて作ったのが始まり。中国圏から熱烈な支持。今までのFWのよいところを取り入れているがHTMLテンプレートの制約を引きずっている。サーバーサイドがメインの考え方を保っている人向け。大規模開発には向かないが分業はやりやすい。後発のSvelteが軽量級としてはその立場を脅かしている。
LitElement、そして Web Components:
Polymerの後継として切り出されたのがLitElement。紆余曲折いろいろあるが、Web Componentsという技術自体は残っていくと思われる。
フロントを機能ごとに分割、別々のFWで作っても一緒に動かせるような「マイクロフロントエンド」という考え方が実現すれば使えるかもしれない。
lit-element.polymer-project.org
このへんも割と主張が強く、特定のFW推しの熱心な人からしたら「戦じゃぁ……」となりそうなぐらいAngularやVue.jsをけっこう批判していたり、なかなか刺激に満ちています。(笑)
React推しの立場からの本であることは踏まえる必要があるかと思いますが、差し引いてもこうしたReact前夜やフロントエンドの歴史の経緯の話はすごく面白い。とても学びになる章です。
8-1.コンポーネントのメンタルモデル
propsが引数でReact Elementsを戻り値で返すJSの関数のようなもの。しかしクロージャの技を使って関数なのに状態が持てる。これがstate。propsとstateどちらかが変わったら再レンダリングされる。戻り値のReact Elementsが変わったらその子要素、孫要素も順番に連鎖して変更されていく。8-2.コンポーネントと Props
stateは少ない方が良くpropsの方が重要。2015年10月のv0.14でStateless Functional Component(SFC)登場、その後名称がFunction Component(FC)になり、2019年2月のv16.8では関数コンポーネントが正式に推奨、React Hooksも公式推奨に……となります。Semantic UIを入れた一覧表示画面で、今度は『SLAM DUNK』の面々一覧表示を題材にしています。スラダンはメジャーなので世代問わず知っていそうですね。react-typescript-cheatsheet.netlify.app
returnを省略できるので、return( )なしで直接JSXを書いても通るんですね。?? の構文を利用した省略法含め、モダンなReactの書き方はだいぶスッキリしている印象です。8-3. クラスコンポーネントで学ぶ State
ReactElement型になってるのですが、JSX.Element型とどっちが良いのでしょうか……?8-4.コンポーネントのライフサイクル
componentWillMount,componentWillReceiveProps,componentWillUpdate があるとのこと。進化が速いフレームワークはこのへんが怖いですね……古いReactの本だと思いっきり載ってそうです。8-5. Presentational Component と Container Component
Presetational ComponentContainer ComponentJust The UIなんだというReactの基本思想と矛盾してないか?と自分も最初は思いました。この考えはReact Hooksを使えば解消できるとして後に撤回されたそうですが、柴崎パイセンの談ではよいコンポーネント設計の観点では常に役立つとのこと。設計の領域は唯一の解のない世界なので両方正しそうでもあります。medium.com
公式の「Reactの流儀」にこのPresentational ComponentとContainer Componentを当てはめる考え方が解説されており、ここを読むとちょっと分かってきた気がします。React力の高まりを感じた……!
9-1. Hooks に至るまでの物語
複数コンポーネントで同じロジックを共通化したりする方法。Hooks登場までの歴史的な経緯も解説してくれてありがたいです。
mixin(ミックスイン):クラスコンポーネントしかなかった初期のReactで、共通化して注入する方法。mixinというプロパティに、別途定義したクラスを[]付きで書く。一見分かりやすいが依存性があり名前の衝突も起きやすく、アプリケーションが複雑化するとさらに深刻になる。HOC(Higher Order Component):関数を引数に取ったり返したりする高階関数を活用する方法がコミュニティ内で発案、HOCライブラリのRecomposeが作られたりで意識の高い開発者には人気だった。Render Props:React Elementを返す関数を受け取り、自分のレンダリングに使う特殊なコンポーネントを使う方法。renderメソッドとはまた別。HOCとRender Propsのどちらがよいか、React公式のコアチーム内や開発コミュニティで意見が分かれて論争があったり諸々。Recomposeの作者がReact公式チームに招かれたりして開発が進み、2019年2月に正式にReact Hooksが登場。これまでの課題を安全に解決し、過去の手法は不要になった。"Hooks"と呼ぶ(らしい)。フレームワーク同士の衝突もあったでしょうし、Reactという括りの中でもまた衝突や論争があったわけで、まるで戦国時代のようです。いろんな試行錯誤や苦労や迷走があって現在があるのだな……としみじみ思います。
9-2. Hooks で State を扱う
const [friendList, setFriendList] = useState<Friend[]>([]); のように書くStateの使い方。TypeScriptの場合は<>内に型引数を渡すと型推論してくれる。HOCライブラリのRecomposeの作者さんが開発に加わっているので、実はインターフェースが若干似ている。this.state.count は最新の値を常に持っているが、関数コンポーネントでHooksを使う時はレンダリングされるタイミングで一定の値。従って前の値を直接変更しようとsetCount(count) してもうまく動かず、setCount((count) => {count+1}) と引数に無名関数を入れるのが正しい。同じstateという考え方でも内部は違うので注意。既存のやり方を知った後アンラーンしてHooksを学び直すのが良いよ、という話で、グランドマスター・ヨーダ様の名言が出てきます。確かにこれから学ぶ初心者から見たらなんだそらって思いますね。こういうところがフロントエンドは厄介ですね……
9-3. Hooks で副作用を扱う
side-effectの意味で使う。関数コンポーネントなら結果はいつも不変となるが、この結果が変わるような処理を実行するAPI。日本語の「注射の副作用」のようなネガティブな意味とは全く違う。useEffect内部の処理で処理に問題がある時はESLintがエラーを出すときがある。公式提供のeslint-plugin-react-hooks にreact-hooks/exhaustive-deps というルールがある。componentDidMount はブラウザへのレンダリング前に行われるが、useEffect だとレンダリング後に処理される。これによってコンテンツのロード前の初期表示処理などが簡単になった。componentDidMount時に関係するデータ全部の初期処理を入れなければならなかったり、時間的な凝縮度が高かった。useEffectを使うと機能ごとにこれを分けられるので、時間的な凝縮度でなく機能的な凝縮度が高まり、よりよい設計になり再利用もしやすくなる。Reactの思想の「宣言的」になる。9-4. Hooks におけるメモ化を理解する
useMemo、useCallbackというAPI。リアルDOMへの参照を残しておくuseRef もある。9-5. Custom Hook でロジックを分離・再利用する
setXxx。サンプルコードではuseTimer。<App>から親のcontainer component である<EnhancedTimer> を呼ぶ。EnhancedTimerの中でuseStateのようにしてカスタムフックのuseTimer を呼び出し。戻り値でpropsでこのuseTimerの実行結果を渡しながら<Timer>を指定。<Timer>コンポーネントがpresentational component で、ロジックなしでpropsを受け取って描画するだけ。container component/presentational componentの使い分けも理解できるし、良いコンポーネント構成だと分かります。「メモ化」ってなんでメモなんだろうとずっと不思議に思っていたのですが、関数型プログラミングの文脈とつながるわけですね…難しいけど学びになる章です。
この【Ⅱ. React基礎編】がReact入門本体。後半だんだん難しくなっていくのでサンプルコードのお遊びネタも少なくなっていきますが、ディープにReactを知ることができます。ある程度基本が分かった上だとJSXの概念の話も納得がいきます。他のフレームワークの批判のあたりは主張が強いですが、React自体の歴史や裏話もすごく面白い。
果たして柴埼パイセンと秋谷さんの世代設定の情報は得られるのか、我々はりあクト!のさらに奥地へと向かった......

本書のサンプルコードのリポジトリ。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をはじめとするフロントエンドフレームワークの入門本まとめ記事最新版が、このブログ内のこちらにあります。
id:iwasiman引退した元TRPGゲーマー。COBOLでもなくPL/Iの金融系レガシー紙駆動開発から脱出→国産メーカー系総合ITベンダーのITエンジニア。所謂SIerのSEだけど仕事はほぼソフトウェアエンジニア/ソフトウェアアーキテクトとして、Web開発でコードを書いたり技術を追ったり時々イベントに行ったり、楽しいエンジニアリングを目指しています。Views are my own.
お気軽にどうぞ~
リンク集:https://lit.link/iwasiman
AIイラスト関連の活動はこちら↓
https://www.chichi-pui.com/users/iwasiman/
https://pixiv.me/iwasiman
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。