2014年にReactを触りはじめて以降、2022年現在まで集中の度合いにバラツキはあるものの、ずっとReactでなんらかのアプリケーションを書いてきました。
その中で様々なアーキテクチャや設計に関する議論がありましたが、特に状態管理についての変遷を自身の体験をもとにまとめてみたいと思います。
多分に昔話的な内容なものの、適度に読み飛ばしてもらいつつ、Reactの状態管理のやや偏った歴史と現在地点の認識の共有になればと思います。
iPhone 4Sが出てスマートフォンを持つ人も多くなり、エンジニアでなくても多くの人が日常的にGmailやMapアプリケーションに触れるようになった時期だったと記憶します。
Webアプリケーションの構築でもフロントエンドへの要求レベルが高くなっていた感覚があり、JavaScriptで動的なViewを構築するケースが増え、自分自身もここに注力していた時期でした。 当時はSPAという言葉を知らず「Submitしない、画面が真っ白になることがない画面を作りたい」と考えていた記憶があります。
当時実装に使っていたのはjQueryとBackbone.jsでしたが、Reactの他にもKnockdown.js、Vue、Angular.jsなどのライブラリを手当たり次第に試して、MVVMや双方向バインディングの概念をみつつも本番導入していくものを決めかねていた状態でした。
自分自身がまだReactのアーキテクチャに関する理解が不十分だったところに出てきた、mizchiさんの「なぜ仮想DOMという概念が俺達の魂を震えさせるのか」は自分には強烈なインパクトをもたらしました。
当時jQueryやBackbone.jsでの実装で自分が悩んでいた課題は、MVCでのModelとViewの同期(イベントのハンドリング -> Model更新 -> ViewのRender)のためには、パフォーマンスのためにViewの差分のみを更新する必要があるものの、差分を正確に考えて実装するのは難易度が高く、結果バグを埋め込むという点でした。
それに対してReactとFluxの根底にある、単一方向のデータフローとそれでも宣言的UI・Virtual Domによる差分更新によってrenderを抑制可能なアーキテクチャは「これだ!」と思うものでした。
一方でFluxはライブラリが群雄割拠の状態でこれだ、と思えるものがまだなく、2015年に最初にReactを本番導入したタイミングではFluxライブラリは採用・実装しませんでした。上位のコンポーネントにStateを集中させ下位のコンポーネントに伝達させる、下位コンポーネントで発生したイベントは最上位まで伝搬する、というProps Drilling(Props のバケツリレー問題)上等な作りにしていました。
今振り返ると、ReactとFluxがセットとして紹介され、宣言的UI・Virtual Domと一方向のデータフローが強く自分の中の設計原則となっていたことが、後のHooks -> Colocation/Lifting State Upの理解を遅くしてしまった部分があると思います。
作成するアプリケーションも一定大きくなりはじめたので、Fluxの考え方のライブラリでも有力となってきたReduxを導入し、その中でのアーキテクチャ、設計パターンを考えるようになりました。
当時はDan Abramovの「Presentational and Container Components」を度々参照していました。
Storeに接続するContainer Component/Presentational Componentを明確に分ける方針がその軸となっており、StoreとConnectされた部分を絞ることで関心事が分離でき、再利用性が高まる、という趣旨です。 記事内にもある通りこの考え方自体は画期的な新しいものだったというよりも、明文化してパターン化された事に価値があったと感じます。 自分が最初期にFluxライブラリを使わず実装した構成も同じ方向でしたが、「Stateを持つコンポーネントを絞った方が保守しやすい」くらいのゆるやかな理解で実装していました。
これ以後の時期の自分にとっての大きなトピックはTypeScriptの導入でしたが、状態管理については大きなアーキテクチャ面での変化があったというよりもReduxのミドルウェアなどよりアプリケーション設計的な内容が話題にあがっていた印象があります。