🎃

Vue2ユーザーが感じたReactの開発体験について

2023/04/19に公開
10

こんにちは!CastingONE の岡本です。

変更履歴

2023/04/25
あくまで弊社で使っている Vue2 と React の開発で感じた違いについての記事でしたが、ユーザーからのコメントを受けて確かに誤解を受けかねない内容でしたので以下の点について修正しました。

  • 記事タイトルの修正
  • 注意文言の追記

はじめに

私は普段、フロントエンド開発を担当しています。弊社のフロントエンドは Vue の 2 系 で開発していますが、React に移行することになりました。私は今まで Vue でしか開発を行ったことがなかったので、これを機に React の勉強を始めました。その勉強を通じて感じた React と Vue の開発体験の違いについて書いていこうと思います。

React の良いと思った点

私自身 Vue の開発経験しかなかったので、React を勉強してみて Vue よりも良いなと思った点を挙げていきます。

確実な型付けができる

React を勉強していて一番感じたことは、TypeScript の型がバシバシ当たることです。Vue は.vueという単一ファイルコンポーネント(SFC)を使用して開発を行うのですが、厳密には JavaScript ではないのでエディタでの補完や構文解析がされません。これらを行うためには、Vetur のような拡張機能を導入する必要があり、導入するとある程度行われますが、完璧とは言えません。例えば、.vue ファイルで props に型を当てたコンポーネントを作成して、そのコンポーネントを import して使う時に props の型を判定してくれないので、違う型を渡してもエラーを表示してくれません。

Parent.vue
<template>
  <Children :title="100" /> // string型にnumberを渡しているのにエラーにならない
</template>

React は jsx という JavaScript を拡張した構文を使用するので、Vue のような事象が起こらず、TypeScript の型が途切れることなく使用できるので、より型安全な開発が行えます。

JavaScript で全て書ける

React の開発は JavaScript で全て記述できます。コンポーネントの作成にjsxという特殊な構文を使用しますが、これも JavaScript に UI がどのような見た目かを記述するために拡張された構文なので、JavaScript の機能を全て備えています。
このおかげで Vue の template のv-ifv-forのような特殊な記述を新たに覚える必要がなく、三項演算子や map でやりたいことが実現できます。

また、何か周辺ツールを導入する時にそのまま書ける点が良いと思いました。例えば、Storybook を導入する時は、Vue の場合 .vue ファイルにコードを書くことができないため色々工夫する必要がありますが、React はそもそも JS ファイルなので、いつもの書き方がそのまま使えます。

Vueの場合のStorybook
const Template: Story<Props> = (args, context) => {
  return Vue.extend({
    props: Object.keys(context?.argTypes || {}),
    components: { Button },
    template: `<Button v-bind="$props" />`
  })
}
Reactの場合のStorybook
const Template: ComponentStory<typeof Button> = (args) => <Button {...args} />

このように周辺ツールを導入する時もシンプルな記述で簡単に行えます。

Vue の良いと思った点

React の勉強を進めていく中で、Vue はこうだった、Vue のあの機能便利だったと思ったことを挙げていきます。

直感的に記述できる

私は Vue を始めた時ほとんど JavaScript の知識がないにも関わらず、それなりの開発ができました。その理由はこの直感的に記述できる点だと思います。

SFC(単一ファイルコンポーネント)

Vue は.vueという SFC で HTML/CSS/JavaScript の記述が一つのファイルにまとまっているので、初学者にとっても関係性が掴みやすかったです。また DOM の変化にリアクティブに特殊な動作をしてくれるディレクティブというのもタグに埋め込むだけで使用でき、直感的でわかりやすかったです。

VueのSFC
<!-- マークアップ -->
<template>
  <div>
    <!-- isLoadingがtrueだとそのタグを表示 -->
    <div v-if="isLoading">
      <!-- ... -->
    </div>
  </div>
</template>

<!-- JavaScript -->
<script>
//
</script>

<!-- Style -->
<style>

</style>

v-model

v-modelは Vue のディレクティブのひとつです。v-modelを使うことで、画面上でフォームの入力値を変更するとコンポーネント内のデータも自動的に変更してくれます。このおかげで、深くネストしたオブジェクトも簡単に更新することができてとても便利です。

v-model
<template>
  <input v-model="profile.name.last" type="text" name="last" />
</template>

<script>
export default {
  data() {
    return {
      profile: {
        name: {
          last: '',
          first: ''
        }
      }
    }
  }
}
</script>

React は v-model のような双方向データバイディングはないので、フォームの入力値を反映させるには、以下のようにイベントハンドラを使用したデータ更新処理が必要になります。また、データがネストしている場合はスプレッド演算で展開するか、愚直に全てのキーバリューを書く必要があり、少し手間がかかります。

v-modelをReactで再現
const [profile, setProfile] = useState({
  name: {
    last: '',
    first: ''
  }
});

const handleInput = (e) => setName(() => ({
  ...profile,
  name: {
    ...profile.name,
    last: e.target.value
  }
}));

return (
  <input type="text" onChange={handleInput} value="text" name="last" />
)

プログラミングを始めて間もない頃に Vue を触り始めた私にとってv-modelはフォームに入力したデータが変数に代入される流れがあまりにも簡単かつ直感的すぎて、逆に何が便利なのかも分かりませんでした。。しかし、経験を積んでいく内に裏側で色々な処理が施されているおかげでこのような直感的な記述ができていることが分かり便利さを実感できました。

ライフサイクルフック

Vue にはそれぞれのライフサイクルの段階で処理を実行できるライフサイクルフックという関数があります。React でも useEffect などの hooks を使用して、再現できますが、Vue はそれぞれのライフサイクルで実行される関数(created や mounted)が用意されており、わかりやすくて大変重宝しました。

ライフサイクルフック
created() {
  // Vueインスタンスの初期化後に実行される
}
mounted() {
  // DOMが作成された直後に実行される
}

まとめ

Vue を始めた頃は、React の書き方(特に jsx)が独特と感じていて直感的に記述できる Vue の方が使いやすそうなのに React の方が人気なのは何故?🤔 「Vue は Easy、React は Simple」ってよく聞くけど、React のどこが シンプル? 😡「Vue より React が大規模開発に向いている」と言われる理由は何?😭 と常々思っていました。ですが、色々と理解が深まるにつれて、Vue は確かに Easy だけど、Vue 独自の記法を新たに覚える必要があるし、TypeScript の型が正確ではない点などを考慮すると開発が大規模になるにつれて Hard になると思いました。それに比べて React は全て JavaScript で書けるので JavaScript を理解していれば新たに特殊な構文を覚える必要がなく、コードの切り出しも行いやすく設計をシンプルに保ちやすいと思いました。また、より型安全である点や周辺ライブラリとの相性を考えると大規模開発に向いていると言われている理由がわかりました。

今では、サクッとアプリケーションを開発するのに向いているのは Vue で、大規模なアプリケーションを開発するなら React と思うようになりました。

終わりに

以上が私が感じた React と Vue の開発体験の違いです。React を勉強することで React も好きになりましたし、Vue がいかに初学者だった私の開発のハードルを下げてくれていたことを実感し、ますます好きになりました。

弊社ではいっしょに働いてくれるエンジニアを募集中です。社員でもフリーランスでも、フルタイムでも短時間の副業でも大歓迎なので、気軽にご連絡ください!

https://www.wantedly.com/projects/1130967

https://www.wantedly.com/projects/768663

Discussion

asip2k25asip2k25

Vue.js 3.2.x (最新バージョン) ではなく、今年度末でEOFとなる Vue.js 2.x と
React を比較した記事ですね。。。

今、React と Vue.js を比較するなら、Vue.js 3.2.x と React を比較しないと。。。

Vue.jsのサンプルコードも、Options API ではなく Composition API での
サンプルコードを載せないと、意味のある比較にならない、ですね。

今(2023/04)、Vue.js 2.x(旧バージョン) と React を比較して、大規模開発に向く
向かないを書いても、何の意味もない、と思います。

りむふぁくしりむふぁくし

Vue.js 3.xでもOptions APIは使えるかと思います。
一方で、Vueの開発者はこれをDeprecatedにしたかったと社内のテックリードから伝え聞いたこともあり、
実質的にはReactと書き方が近いCompositions APIが強く推奨されている状況だと思っています。

asip2k25asip2k25

Vue.js3.x でも、Options API を利用できますが、開発体験の違いや大規模開発に
向く向かないを云々するなら、Vue.js3.0.0(2020/09/19)リリースから2年半を
過ぎている現在、旧バージョンであるVue2.x & 後方互換性のために残されている
(と考えられる)Options API を対象にして、比較記事を書くのは、エンジニアとして
どうなんでしょうね? (意図的になのか、比較対象にしているVue.jsのバージョンは
書かれてませんし。。。)
開発体験の違いや大規模開発に向く向かないを云々するなら、現行の最新バージョンである
Vue.js 3.2.x & 公式に推奨されている Composition API を比較対象にして、文章を
書くべきなのでは?
(それか、旧バージョンであるVue.js. 2.x & (非推奨の) Options API を比較対象にしている
ことを明示すべき、ですね。)

KatEusKatEus

エンジニアとしてどうなんでしょうね?

筆者のエンジニアとしての素養に対する批判を、記事に対する指摘に混ぜて行うのは良くないと思います。

このコメントを見た人がアウトプットを躊躇してしまう用になるかもしれませんし、発信者も今後の発信をやめてしまうかもしれません。

asip2k25asip2k25

エンジニアとしての素養に対する批判はしてませんよ。
技術記事を書く際のスタンス(姿勢)?に対する批判?です。

技術(に関する)記事を書く際、バージョンが違うと変わってくるのなら、
記事が対象とするバージョンを明示すべきです。
古いAPIと新しいAPIが併存しているのなら、記事が対象としているAPIが
どちらかor両方かを含め、それについても触れておくべき、でしょう。

↑の記事のように、著者の知ってる範囲内(Vue.js2)で、比較記事を書くのなら、(訂正前の)
元の記事の「Vue(.js)とReactの開発体験の違い」(確か、このタイトルだったはず)、
内容にも、記事が(比較)対象にしているVue.jsのバージョンについて、一切、触れられて
いない、ではなく、「Vue(.js)2とReactの開発体験の違い」と比較対象のバージョンを
タイトルに明示して、本文にも、Vue.js2(古いバージョン)とReactの比較であること、
を明示すべき、でした。
(現在は、タイトルにも本文にもVue.js2とReactの比較であることを明示する形に訂正
されています。)

WEBフロントエンドの最近の状況に詳しくないorを知らない人間が、元の記事を読めば、
↑の記事の著者のバイアスの掛かった本文の内容を鵜呑みにして、
Vue.jsの古いバージョン と React の比較記事、であるにも関わらず、
最新の情報に基づいた比較記事である、と誤認してしまう可能性がありました。

Vue.jsも Reactもそれ以外の〜も 古いバージョンと最近のバージョンでは、
色々と(細かなところを含め)変わっているので、記事を書く際には対象とする
バージョンを明示しておいたほうがよいですね。

(記事の対象が何であるかに関わらず、古い記事なのに読まれている記事について、
読者に配慮して、「〜の古いバージョンを対象にした記事なので〜」な感じの文言を
著者が後から先頭に追記していることもありますね。)

jay-esjay-es

Vue 3 + Volar では TypeScript のサポートが大幅に向上していて、props の型が間違えていたらきちんとエラー表示されたりするので、一度さわってみるとよいかも知れませんね。

Type 'number' is not assignable to type 'string'.

RimlRiml

Vue2.7(script setup) + Volarも同じくpropsの型エラーでてくれるので結構体験よかったりします!
3に移行できなくとも2.7は移行しやすいため是非この体験も試して頂きたいです!

ashash

現段階でVue3にまだ移行できていない組織も山のようにあるはずで、その人たちにとってOptionsAPIを使った比較はわかりやすいかもしれません。どのようなテーマであれ、アウトプットに対して敬意を払うべきだと思います。

正確さに問題があるならその点を論じれば良いだけで、エンジニアとしてどうか、などと苦言を垂れる暇があるのでしたら、ご自身で記事を書いてZennのコミュニティに貢献されるのがよろしいのではないでしょうか。

spectorspector

どうしたんだみんな
まるで劣等感の塊じゃないか

発信者に敬意をはらいたまえよ