社内の開発プロジェクトでReactを導入して開発しました。作成したアプリはいわゆるマネジメントに利用するもので、従業員の等級や配属先などを管理する管理職向けのアプリです。
頻繁に操作を行ってデータの編集を行いますし、データ変更時にある程度複雑なバリデーションを行ってデータの整合性を保証しなければいけないので、Reactに踏み切った次第です。
社内に知見がなく、jQueryオンリーの開発から独自でReactを導入してhooksAPIの利用、react-reduxによるステート管理など一通りやってみたというところです。
この記事では、実際にプロジェクトで利用して感じたメリット・デメリットについて紹介したいと思います。ちなみにサーバーエンドはPHP(CakePHP)を利用しています。
目次
Reactを利用するメリット
1. ロジックやスタイリングの責任範囲を明確にしやすい
SPA(シングルページアプリケーション)をjQueryオンリーで実現しようとすると、どうしてもコードが煩雑になってしまいます。様々な関数で様々な場所のDOMを直接いじる多対多の関係になり、役割分担が難しいのが正直なところ。
jQueryをメインに利用した開発では、「文書構造(HTML)」「スタイリング(CSS)」「動的な処理(JavaScript/jQuery)」という役割分担となりますが、アプリが巨大化してくるとクラス名が接頭辞だらけで訳が分からなくなったり、JavaScriptの複数の関数間で整合性が取れなくなるなど限界を感じていました。
一方、ReactなどのJavaScriptライブラリを利用した場合は「コンポーネント」という単位で管理することになり、文書構造・スタイリング・動的な処理を極力ローカルに管理できます。そして、コンポーネント間は状態(State)によって接続されます。
コンポーネント単位で管理するという前提ですと、必然的にJavaScriptのコードも適度な粒度に分割されやすく、管理しやすいというのがメリットとしてありました。
2. 状態管理がしやすく実装をシンプルにできる
Reactの最大のメリットである状態管理のしやすさもSPAを作る上で大きなメリットを感じました。SPAでは大量の状態を管理する必要がありますが、状態が変更されると関連するコンポーネントがすべて自動更新されるというのが大変に便利です。
状態を具体的に紹介しますと、以下のようなものです。実際は変数に入れて管理します。
- モーダルやダイアログが開いているかどうか?
- (非同期通信で)データを読込中かどうか?
- フォームの入力内容が有効か?
- フォームの入力内容そのもの
jQueryだけで開発をした場合、「この変数が変更されたら、こういう処理をする」という関数を一つ一つ書いていかなければならず、煩雑になってしまいます。
3. 優れたUIライブラリが多い
今回のプロジェクトではMaterial UIというマテリアルデザインのUIライブラリを利用しました。こちらはGoogleライクなUIを簡単につくることができます。
例えばBootstrapなどは、HTML要素に特定のクラスをつけることでスタイリング(CSS)や動的処理(JavaScript)のテンプレートを利用するものですが、Material UIの場合はコンポーネント単位でパーツが提供されています。
この点がReactと大変親和性が高く、コンポーネントパーツに対して直接イベントハンドラ(onChange, onClickなど)を渡すことが出来ます。
Material UI https://mui.com/
その他にも、Ant DesignやReact BootstrapなどのUIコンポーネントライブラリや、Framer Motionというアニメーションを簡単に実装できるライブラリもあり、複雑なアプリケーションをつくるための環境が整っています。
4. サーバー側の処理を(ある程度)シンプルにできる
コンポーネント単位で文書構造・スタイリング・動的処理を管理できるようになると、ある程度複雑な計算をフロントエンド側で実装しやすくなります。(管理コストが従来に比べて低いので)
そのため、従来は利用用途によってサーバ側で細かく関数をつくるような実装になっていましたが、Reactの導入によってサーバー側の関数が減り、シンプルになりました。
サーバエンドがフロントエンドに対して行うことは、
- アクセスしてきたURLを解析して、適切なビューを返すこと
- 必要なJSONを飛ばすこと(GET)
- 飛んできたJSONを元に処理をすること(POST/DELETE)
くらいになりました。
これまではテンプレートファイルに埋め込む変数を1つ1つサーバ側で取得して、サーバー側からフロント側に送って・・・としていたのですが、フロント側である程度複雑な計算ができるようになったので、その必要がなくなりました。
サーバー側からは大きなJSONをフロント側になげて、データのフィルタリングやデータ整形はJavaScriptで実装することで、サーバー側とフロント側が以前より疎結合になりました。
もちろん、サーバエンドでもPOSTされたデータのバリデーションや権限管理などやらなければいけないことは残っていますが。
それと個人的には、フロントとサーバーを疎結合にすることでサーバー側の関数を別の人に開発依頼するときに、フロント側の実装を知る必要がないというのが大きかったです。
飛んでくる引数やJSONの形式と、それに対してのレスポンス(JSON)さえ定義できれば、フロント側が未完成でも実装できるというのはありがたいところ。
Reactを利用するデメリット
1. 学習コストがかかる
Reactによる開発は、これまで行っていたjQueryによる開発とは全く別物でした。そのため、まずはコンポーネント志向という全く新しい概念を理解するところから始める必要があります。
Reactに関しては日本語の情報も充実してきていますが、周りにReactを利用している人がいないと学習がなかなか大変でした。jQueryでは必要がなかったWebpack、Babel、reduxなどを理解し、設定しなければいけないのでその点が大変でした。
ただ、ReactのチュートリアルやDocsはとても分かりやすく、日本語も丁寧で読みやすいのでその点はとても良かったです。
2. 不慣れな場合、ページが重くなりがち
メリットでも述べましたが、Reactで管理している状態(State)が変化すると、その状態を利用しているコンポーネントが自動更新されます。逆に言うと、使い方に不慣れだと状態の変更時に余分なコンポーネントが頻繁に再レンダリングされてページが重くなります。
Reactでは仮想DOMという仕組みをつかってDOMの更新コストを抑えていますが、それでも実装を間違えてしまうとパフォーマンスがでないので、その点注意が必要です。
3. コンポーネントの設計までは面倒を見てくれない
当然といえば当然ですが、コンポーネント志向のライブラリとはいえコンポーネント設計は自分で行う必要があります。
コンポーネントが肥大化するとロジックが複雑化して管理コストが上がってしまいますが、コンポーネントを小さくしすぎるとコンポーネント間の関係性を追うなど全体像をつかみにくくなります。
適切なコンポーネントの粒度が分ければいいのですが、その判断は慣れが必要そうです。一応、Atomicデザインなど指針になりそうな概念はあるものの、あくまでAtomicデザインはデザインの指針であって必ずしもコンポーネント設計のベストプラクティスにはならなそうです。
4. 静的なページではReactを使わないほうがシンプルになることも
Reactが向いているのは、TwitterやFacebookなどのSNSを始めとしたユーザが操作を頻繁に行うアプリケーションです。
逆に、ニュースサイトやブログサイトなどはページを更新して読むだけなのでReactのメリットをあまり受けられないです。そのため、静的なページにおいてはReactを使わないほうがシンプルな実装になることもあります。
例えば、記事一覧を出すときはPHPであればHTMLテンプレートの中でループを回せば同じデザインの要素が記事の数だけ出てくるので。。
あくまでReactのメリットが最大限発揮されるのは、操作をすることが多いSPAにおいて、ということですね。
まとめ
以上、Reactを使って感じたメリット・デメリットをまとめてみました。
個人的にはコンポーネント単位でフロントエンドを作っていくスタイルはとても楽しいですが、楽しいと感じるまでの学習がそこそこ大変でした。
ただSPAを作る際にはとても有効であることを確信しましたし、ユーザの操作に対して適切なフィードバックを返すために複雑になりがちなコードを適切な粒度で管理しやすくなるのは間違いないです。
業務用ツールやSNSのようなダイナミックなアプリを開発する際にはReactが大変良いと思います。僕はまだ使ったことが無いですが、React Naitiveというフレームワークを使うとスマホ用アプリをReactで開発できるそうです。
今後も使っていきたいと思います。