Reactを触ってみてVueとの違いをまとめてみた
こんにちは。Nonです。
私は、Laravelに付属しているという理由からVueを採用してフロントをいじってきた経緯があります。
Vueしか触ったことのない私が、フロントをしっかりと勉強する機会が最近増えてきました。
React勉強会なるものを社内で実施した結果、VueとReactの違いに気づいてきたので、そろそろまとめようと思い記事にしました。
とはいえ、何番煎じやねん。という感じなので、感想は他のサイトで上がっている内容と重複する部分もあるかもしれません。(できるだけ私個人の感覚も取り入れて記事にしたいと思います。)
参考記事はページ最下部に貼っておきます。
ということで、下記から「ある一点」に注目して比較してみます。
なので、一概にこっちが...というわけではありません。
それぞれの特徴を考慮してプロダクトを進めていくべきであり、〇〇さんが言ってたからこっちとか言うわけではありません。
採用する背景で重要なのは
- 経験者の有無、または今後のスキルセット
- ビジネスサイドを考えたアーキテクト
など、包括的な開発背景の裏付けを基に採用を進めるべきというのが持論となります。(両方わかって両方触れる人がいれば完璧なんですが...w)
特徴
特徴については、他のサイトでもいっぱい語られていますね。
なので、私の価値観でサクッと済ませます。
Vue
- 技術の分離
- Vueのテンプレート技術の採用はほぼ必須
- HTML、CSS、jsの技術を明確に分けやすい。(Scoped CSSとか)
- UI / UX的。
- 画面の内容がメイン
- HTML / CSS がわかるだけでなんとかなる。(長所であり短所)
- 冗長ではないため、簡潔。
React
- 関心事の分離
- Class / Entity / Component的。
- 各コンポーネントはClassでありEntity。
- HTML(つまり各コンポーネント)をEntityクラスと受け止めるとすんなり開発が進む
- javascriptのパワーを最大限発揮できる。
- jsxはjsの拡張(これがいいって感じる人は多いはず。)
- js(jsx)を中心にしているため冗長な分、設計がしっかりしている
お手軽さ
お手軽さという点に注目して比較してみます。後述する開発効率と重複してしまいそうですが、ここでは学習コスト、設計コストという面に注目します。(初速とも捉えることができます。)
Vue > React
Vueの特徴の一つに技術の分離があります。WEB / CSS さえ知っていればある程度のコンポーネントを作成できますので、学習コストはVueに軍配が上がるでしょう。
Reactはjsxに設計構想 / 方針についての深い理解を特に求められます。いい意味でも悪い意味でも作業者に高い期待を求めることになります。
- フロントでガッツリとした処理を書かない
- 実装へのお手軽さを重視
- フロント技術の網羅的な知識を持っていない人が参画し、作業者となっている
こういう時はVueの方がお手軽です。
特にマークアップエンジニアやデザイナーが担当者の場合顕著です。
Vue
WEB / CSS 部分を技術的に分離できるので、コーダー、デザイナーはこれまで通りの作業で作業を終えることができ、あとはjsをある程度知っている人にバトンタッチすることができます。
また、画面の動きを実装するという面でも、簡単なjavascriptの動作を勉強するだけで実装することができます。非同期処理や設計に関しては他のエンジニアに任せるという開発運用方法ですね。
例えば、styleやclass要素の変更を加えるときstringで十分扱えるので、特定の関数がフラグを判定しstringを返すというだけならjs入門したばかりの人でも十分しっかりと書けることでしょう。
React
Reactのjsxにstyleやclass要素の変更を加えるときにはjsxの構文を知っている必要があります。
基本的にpropsは関数、オブジェクトで有るべきなのがReactです。マークアップエンジニアやデザイナーにはここが最初の障壁となるでしょう。
(もちろんプログラマ的にはClassと受け止めることができるのでメリットです。今は他の方を巻き込む時を想定しています。)
更に詳しく
技術の分離が明確。HTML / CSS / jsの技術を明確に分けやすい。(特徴の一つ)
私の関わっているプロダクトは新機能追加の重要度が高く、開発スピードも求められます。フロントでの重大な処理もありません。今思うとVueを採用してよかったなと思います。
また、
- コーディングができないが、UI / UXに特化したデザイナー
- javascriptをあまり知らないが、HTML / CSSを熟知しているコーダー
がプロダクトに参画しています。
この時、デザイナーが作成した画面デザインをコーダーが再現することになるのですが、コンポーネント設計がされているフロントにコーダーが手を入れるとき、
- javascriptにHTMLが実装されているReact
- templateとjavascriptを分離されているVue
とではVueのほうが学習コストが低く、コーダーレベルでも手を出しやすいように感じました。
(もちろん、HTML / CSS / javascriptをきっちり分離しているプロダクトではこの対象ではありませんが、私のプロダクトは前述の通り実装スピードを重視しており、引き継ぎ時点でこのような設計はされていませんでした。)
特に。
を採用しているとき、Reactはjavascript、jsxの知識をコーダーに求めることになりますが、Vueの場合はtemplateに書かれたpropertyに注意するだけでHTMLをそのまま書く感覚に近い気がします。
設計
設計という点に注目して比較してみます。
先に書いてしまうと、この章をうまく言語化できていません...申し訳ない。
Vue < React
少し具体例を上げるとするなら下記のような感じ。
私はPHPをよく使うので、Smartyをいじる機会も多いのですが、
Vue
- Vueは予め存在するテンプレートに対して処理を実行するイメージ
- 処理技術と描画技術を分けて書くため、Smarty(テンプレートエンジン)に処理を書きまくる感覚
Smartyに処理が書かれまくっているのとても嫌。
私が関わっているプロジェクトではそれを嫌って処理部分と描画部分を切り分けるような構造にしていますが、どうしても描画部分に引っ張られる部分がまだある。
React
- PHPでHTMLをどう描画するか記述しているイメージ
- 処理オブジェクトと描画オブジェクトを定義して関心事に分けて書くため、処理部分でHTMLを書きまくる感覚
上記から
- 設計を厳密にしたい
- 堅牢性を高めたい
- ビジネスロジックをフロントにバリバリ書く
この辺を考慮するならReactを採用するべきでしょう。
更に詳しく
フロントでバリバリ処理を実装する。(ここで言う処理とはデザインの動的変更や、アニメーションの実装ではなく、文字通りフロントでビジネスロジックを実装するパターンを指します。)
jsxを採用しているReactは関心事の分離に特化している印象を受けます。
jsxについての説明は
マークアップとロジックを別々のファイルに書いて人為的に技術を分離するのではなく、React はマークアップとロジックを両方含む疎結合の「コンポーネント」という単位を用いて関心を分離します。後のセクションでコンポーネントについては改めて詳しく紹介しますが、現時点で JavaScript にマークアップを書くことが気にくわない場合、こちらの議論で考えが改まるかもしれません。
Vueはどちらかといえば技術の分離。お手軽さの章で述べたように、チームメンバーの技術の守備領域が明確になっている場合はこの恩恵を受けることができる。
対して、Reactは関心事の分離。プログラマはHTMLのことを熟知していなければなりませんが、ビジネスロジック処理と描画処理(あくまで処理であることが重要と思います。)を切り分けて考えることができるので、アーキテクトに恩恵を受けることでしょう。
これのどこかいいか、何が言いたいかと言うと、技術の分離ではないので全てをjs(jsx)でまとめる事ができます。
- js(ts)のみでコンポーネントを設計したい
- jsコードの中でコンポーネント呼び出しを行い、htmlを変更したい
などの実装がすべてjs(jsx)で完結するのがReact。とも感じています。
例えば、jsの中でコンポーネントを実装しようとするとき、
Vueの場合
export default {
props: {
label: {
type: String,
required: true,
}
},
data() {
return {
// データ定義
}
},
template: '<button>{{ label }}</button>',
// or
render(createElement) {}
}
となるでしょう。ここのtemplate
の部分がstringで書かれることになります。これがとても気持ち悪く感じます。
それなら<template></template>
を採用しろ、という話になるのですが、その場合、jsのみで完結することができません(それマークアップじゃんと捉えられてしまいます)。
どうしても文字列を書く部分で出てきてしまい、設計がきれいという話にならなくなってします。
ではrenderではどうか? という話になりますが、jsxではないVueではcreateElement
を利用して一つ一つDOMを作成しなければなりません。これが非常に面倒臭いです。プログラマチックといえばそのとおりですが、可読性が下がるのは間違い無いと思います。
Reactの場合
いつもの感じで書けばいいです。
import React from 'react';
class MyButton extend React.Component {
construtor(props) {
super(props);
this.state = {
// データ定義
}
}
// 関心事の分離的。
render() {
const button = <button>{this.props.label}</button>
return button;
}
// 技術の分離的。
render() {
return (
<button>{this.props.label}</button>
);
}
}
render
の部分でHTMLを書くのが基本となるので、設計上とてもわかり易い上に、jsxでHTMLを直接書く感覚にとても近いです。
何より、突然このコードを書いてもjsなら起動します。これがtsと相性のいい理由でもあります。フレームワーク間で結合のための設定を(比較的)しなくても済むのですから。
jsxについての説明は
このおかしなタグ構文は文字列でも HTML でもありません。
これは JSX と呼ばれる JavaScript の構文の拡張です。UI がどのような見た目かを記述するために、React とともに JSX を使用することを私たちはお勧めしています。JSX はテンプレート言語を連想させるでしょうが、JavaScript の機能を全て備えたものです。
とあるように、一つのObjectと捉えることができるもの大きな違いです。
typescript(堅牢)
堅牢性に注目してみました。
Vue < React
堅牢性、特にtypescriptを採用する場合が顕著です。
このあたりはそれぞれのフレームワークにtypescriptを導入してみたらわかると思います。
導入については他の有用な記事にお任せしたいと思っていますが、Reactはtsとの相性が抜群です。
この時点でプログラマ視点からみた場合、堅牢さで軍配が上がるでしょう。
TypeScriptの導入障壁としてならVue ≒ React
結局は両フレームワークともに状態管理をメインに行うフレームワークなので、この部分さえ型厳密にしてしまえばいいのです。なので、導入障壁は同じ位と勝手に見てます。
しかし、導入後恩恵を受けやすいのはReactなので、このようにしました。
理由
render
部分に注目するとVueはstring
で、Reactはjsx
で書かれていることにも注目できます。
tsで型厳密したときもReactの方がrenderへの恩恵を受けやすく、マークアップ部分が書かれたところも型厳密にしやすいことがわかります。(jsxはtsxとして型厳密にできますので。)
処理部分でも同じです。jsxはjavascriptの拡張なのでtsに置き換えやすく、関心事の分離が容易な上に型厳密までできるという堅牢さを持っています。
Vueのtemplateはjsxではなくstring
かcreateElement
なので、この恩恵を受けづらいです。
Vueにjsxを導入する方法はありますが、それならReactを採用するでしょう。(そもそもそこまでしてVueの便利なテンプレート技術を捨てる理由がわからないです。私がそこまでするならReact移行を考えます。)
また、Vueではprops
のバリデーションを実装できるのですが、typescriptの型厳密とVueのバリデーションでtsでNGでもVueでOKとなる場合があります。(設定のせいかもですが、この設定がそもそもめんどい)
あと、Vueにts導入しようとすると、正味わけわからんくなる。
VueのTSサポートについて
TSのサポートは微妙。Vueは手軽さとアバウトさが売りなのでしょうがないのかも。
確かに。
型付けがやりにくい(子Componentの場合いちいちデコレータを書かなくてはいけない)
型定義が間違っていてもコンパイルが通ってしまう(スキーマ !== 型定義 の場合でもとりあえずコンパイルは通ってしまう??)
上述した、Vueのprops問題。
子コンポーネントにpropsを渡す際に必須であれば
required: true
と定義するが、これは型定義で解決するべきことのはず。
そのとおりだ...
開発効率
開発効率という点に注目してみたいと思います。お手軽さと重複してしまいそうですが、ここではどちらかというと 実装時間 という観点に注目したいと思います。
Vue >= React
実装スピードは慣れという部分も大きいので、最終的には同様の効率になるかと思います。設計がしっかりできる分Reactのほうが効率いいように見えますが、そのために冗長な記述を大量に記載するのが特徴なので、結局トントンになるかもしれません。
Vue
- いい意味でアバウト
より引用
- 役割分担に非常に相性がいい
- 画面に必要な機能をVueテンプレートがたくさん用意してくれている
React
- 堅牢なのはいいが、その分厄介(面倒)な部分もある。(〇〇したいだけなのに、ここまでしなきゃいけないの!?ってのは慣れてきた今でも感じることが多い)
- 役割分担がされておらず強力なフロントエンジニアがいる場合は個人のパワーに任せやすい。(↔エンジニアの力量に左右されやすいかも)
- 設計手法が明確にチーム内で共有されている場合はそこまで遅くならない(はず)
結局どっちを採用すればいいの?
冒頭にも書きましたが、
Vue
- デザイナーがフロントのメイン担当
- 役割分担がしっかりしていて、同時にその作業者である。
- デザイナーもコーディングすることがあるとか
- コーダーがフロントではなくマークアップエンジニア的とか
- フロントにそこまで興味がない人が多い
- フロントでビジネスロジックを書くことが少ない
- 特定のページにのみ導入したい
- ちょっと試しにやってみたい。
- 部分的導入
- 速さを求めたい
- 学習コストをかけたくない
このような場合はVueでしょう。
React
- プログラマがフロントのメイン担当
- フロントエンジニアがたくさんいる
- 強烈なフロントエンジニアがいる
- 作業者がHTML / CSSに精通しているエンジニア
- 役割分担というよりチーム開発
- デザイナーは画面デザインのみで作業者ではない
- コーダーのjsの理解が深い(エンジニアと呼べるレベル)
- 堅牢さを重視
- 重要なビジネスロジックが存在する
- 画面でもEntity的な考えを要求する
- フロントはこのようにあるべきという方針が存在する
- フロントとバックの明確な分離
- デザインとフロントの明確な分離
このような場合はReactでしょう。
最後に
ちょっと文章多めですみません。書き出したらこれもあるな。あっ、あれも。といった感じで追記していったので、まとまりが悪いかもしれません。
私はVueのほうが、Reactの方が...と言及するつもりはありません。
やはりチーム内、会社内で事情知るエンジニアに選択をせまり、答えを出した人に従うべきかと思っています。
結局、私の担当するプロダクトでは
- デザイナーが技術的背景を持たない
- HTML / CSSに特化したコーダーがいる
- 納期がすぐそこ
といった、止むに止まれぬ事情があったのでVueを採用して書かれています。
しかし、弊社にもフロントを重視する考えが浸透してきて、フロントに対して前向きに取り組むような方が増えてきました。
この背景から中長期的にはReactの方がよかったかもと考えるようになってきて、少し違いをまとめてみようと記事にしました。
Reactへの移行も考えていますが、Vueが堅牢ではないとは明確に言えないので、Vueのts対応を進めて過去の頑張りをブラッシュアップする方針でもいいかもと思っています。(優柔不断)
React勉強会については記事にできていませんが、PWA周りや、React Nativeについては今後も投稿していきたいと思います。
そのときはよしなに。
参考
概ね私と同じ考え方でした。引用させていただいた部分も多いかも。
ありがとうございます。
あと、パフォーマンス面にも触れていていいと思った記事です。GraphQLについて言及しているものいいなと思いました。
私はこの記事に続いて、中長期的な戦略としてVue→React移行がしやすい設計をVueの段階でしておくことも重要だと考えています。