Reactはフレームワークなのか?:負債ではなく投資のための質問
この記事で伝えたいメッセージ
- Reactはレンダリングライブラリである。
- 自分の問題を他人のコードで完璧に解決することはできない。これに関連する技術負債は常に念頭に置くべきだ。
- フレームワーク、ライブラリの概念と特徴が何かを明確に知り、それに応じて自分が直面した問題に適したソリューションを選択できる基準を育てるべきだ。
概要

Reactは公式にはライブラリである。
しかし、Reactを単にライブラリとして見るべきなのか?という話がよく聞かれる。
まず私の考えを明かすと、「Reactはライブラリである。」と説明できると思う。断定するのはあまり良い習慣ではないが...少なくとも私の基準ではこう確実に言えると思う。
では、これから一つずつ見ていこう。
フレームワークとライブラリ
Reactがフレームワークなのか、ライブラリなのかを判断するために、まずこの二つの違いを明確に理解する必要があるだろう。
フレームワークなしのフロントエンド開発の著者である「フランチェスコ・ストラッツッロ」はライブラリとフレームワークの区分を次のように説明している。
フレームワークはコードを実行する。コードはライブラリを実行する。
私もこの観点がフレームワークとライブラリの違いを明確に示していると思う。
フレームワークを使用するということは、つまりツールが強制する方法に従って開発が行われるという意味である。
より明確に表現すると、フレームワークがアプリケーションの制御フローを管理し、開発者はフレームワークが提供する構造の中でコードを書くということである。
反対にライブラリは、開発者が管理する制御フローの中でこれを呼び出すというのがより明確に表現される違いであると言える。

図で表現すると上記のようになる。
フレームワーク方式とは?
本を基に学習しているので、著者の考えを外すわけにはいかないと思う。
作業を処理する時に「フレームワーク方式」を使用しているならフレームワークと見なせる。
著者が本で提示したフレームワークの判断基準である。
フレームワーク方式(Framework's way)とは何だろうか?
本を通じて接した私にとって新しい概念である。
簡単に言えば、ツールを使用するために強制されるもので、Angularを例に説明すると次のようになる。
- 言語:TypeScriptがAngularエコシステムの事実上の標準である。(de facto)
- 依存性注入:要素(Element)がAngularアプリケーションで通信するには、タイプに応じて依存性注入(dependency injection)メカニズムを使用する必要がある。
- Observable:Angularは標準方法であるPromiseの代わりにObservableを使用したリアクティブプログラミング用ライブラリであるRxJSを基に設計されている。
上記のいくつかの要素は必ずしも使用されなければならないものではないが、コミュニティユーザーにとって事実上の標準(de facto)のように使用される方式である。
結局フレームワーク方式とは、フレームワークであるかどうかに関係なく、コミュニティユーザーによって事実上の標準のようにあるルールが強制され、普遍化されて使用されることを意味すると見ることができる。
フレームワーク方式観点でのReact
Reactもこの観点で見るとフレームワーク方式に該当すると見ることができる。
React.createElementやクラス文法などを使用してVanilla JSのように命令型方式でDOMを操作できる。
しかし、現在のReactで普遍的に使用される方式はJSXなどに基づいた宣言型方式である。
また、最近のReactコミュニティでは関数型方式の使用を推奨している。
これに従ってuseState、useEffect、useRefなどの宣言型方式で使用することが普遍化された。
この観点をより理解するためにコードを見てみよう。
Reactユーザーなら命令型方式に違和感を感じるかもしれない。
しかし、厳然として動作する方式である。しかし、私たちはコミュニティや公式ドキュメントなどで推奨される方式に慣れているため、このようなコードの書き方がやや不自然に見えることがある。
これがまさにフレームワーク方式である。フレームワークではないが、コミュニティによってフレームワークのように使われる事実上の標準方式。
Reactはそれならフレームワークなのか?
作業を処理する時に「フレームワーク方式」を使用しているならフレームワークと見なせる。
著者の基準通りならフレームワークと言えるだろう。
ただし、私の考えは少し違う。
フレームワークの基準はフレームワークとライブラリで確認した基準で評価するのが正しいと思う。
実際にReactの場合、vanilla JSで書いたコードフロー内で一部分だけReactで書いて使用できる。
つまり、開発者が書いたコードのフロー内でReactを実行できるということだ。
Reactをフレームワークとして定義し、上記の基準通りReactのフローに従って開発しなければならないなら、下手をすると柔軟な思考方式を失う可能性があると思う。
さらに、ツールが解決しようとする問題があるはずだが、その本質を見逃す可能性があるかもしれない。
だから、Reactはライブラリとして見ることがより良いアプローチ方法だと思う。
技術負債
ある人はこのような区分をなぜ知る必要があるのか疑問に思うかもしれない。
これを深く扱った理由はフレームワークの使用は無料ではないからである。
ここで言う無料という概念は、オープンソースのようにお金を払わずに使用するという意味ではない。メンテナンスの観点からフレームワークを使用することで発生する追加的なコストについての話である。
著者はこれについて、ワード・カニンガム(Ward Cunningham)の技術負債(Technical debt)を例に挙げている。
汚いソリューションを選ぶほど技術負債は増える。

完全に理解せずにフレームワークを使用することは、メンテナンス段階で様々なエラーや修正事項に対するリスクを抱えていくのと同じだ。
これは表に出ないだけで、いつかは返済しなければならない部分でもある。
そして、当然ながら負債に伴う利子も発生する。
シンプルで極端な例として、プロジェクト初期に使用していたフレームワークを別のフレームワークに置き換えることと、10年間使用していたフレームワークを別のフレームワークに置き換えることにかかるコストを考えてみよう。
後者は前者に比べて膨大なコストを要求する。
技術投資
他人のコードは私の問題を解決するのに最適な方法にはなり得ない。
著者は技術負債を理由に上記のように意見を伝えている。同時に、技術投資という概念も提示している。
すべてを実装できれば良いが、実はこれはソフトウェアの特性に逆らうことでもある。
個人的な意見として、ソフトウェア産業が他の産業と異なる最大の要素は複製が可能だという点である。
単純にCTRL+C / CTRL+Vでどんなファイルやソフトウェアでもコピーできるではないか?
これは言い換えれば、再利用可能だという特徴を含んでいることを意味する。
家を売買する時、事業をする時にローンを組むように、技術負債は必ずしも悪いものではない。
負債を適切に管理できればむしろこれは投資になることもある。
結論:重要視すべきこと
技術負債と技術投資という観点は、フレームワークを導入する時にコストの観点で考慮すべきことを示唆している。
結局合理的な理由で適切で速いソリューションを導入して問題を解決することが核心であると言える。
**Reactはフレームワークなのか?**というやや突飛に見えるかもしれない質問を投げかけ、記事で判断根拠を整備した理由もこのような観点からのアプローチだった。
そしてさらに進んで、より明確な判断の根拠を下すためにライブラリ/フレームワークのソースコードを調べ、場合によっては直接実装を試みることになった。
ツールをうまく扱うことももちろん重要だが、このツールに埋没せず、今の自分の問題に合っているか適切な判断根拠と、使い方を学ぶためにも本質的な要素についての学習が必要だと思う。
この記事が他の開発者にも少しでも役立てば幸いである。