Vueを勉強して業務でさわりはじめ、1年半が立ちます。
フロントエンドエンジニアとしてできることを増やしたかったのと、今後のリプレイス案件に対応するためReactを勉強してみました。
(できるよう仕事増やしたい!!)
Vueが理解できていると、フロントエンド全体の考え方やブラウザについての知識がついているので、Reactも勉強しやすかったです。
人間、感情が動いたときの記憶力は定着率が1.5倍と聞きます。
なのでVueが理解できていると、ここVueとほぼ一緒やん!全然違うやん!と行く風に感情が動きました。
ReactでもVueでいう〇〇だよね~という感じで似ている部分も多く、理解のスピードも速いように感じました。
※間違っているところがあれば意見ください!!
使用した教材
私が使ったのは、React – The Complete GuideというUdemyのコースです。
Udemy
【2024年最新】React(v18)完全入門ガイド|Hooks、Next14、Redux、TypeScript
この教材は、ただのコードの書き方だけでなく、Reactの思想や背景も丁寧に解説してくれます。
Vueの経験がある方であれば、「この部分はVueの〇〇に似ている」とすぐに理解できるのでおすすめ。
VueとReactで似ているところ
VueとReactはどちらもモダンなフロントエンドフレームワークで、コンポーネント指向の開発スタイルを採用しています。
これにより、小さな部品(コンポーネント)を組み合わせてアプリを作るという、全体的な構成は似ています。
記述が違うものの、概念的にほとんど同じ部分をまずは具体例を挙げながら共通点を見ていきます。
1. 状態管理(ref
とuseState
)
Vueではref
、ReactではuseState
を使ってコンポーネントの状態を管理します。
どちらも「リアクティブな状態を持たせる」という考え方に基づいています。
ただし、Vueではref
オブジェクトの中の.value
にアクセスしますが、Reactでは配列の分割代入で状態とその更新関数を取得するという違いがあります。
例:カウンター機能
Vueの場合
Vueでは、状態をref
でラップし、increment
関数で直接値を更新します。
<script setup>
import { ref } from 'vue';
const count = ref(0);
function increment() {
count.value++;
}
</script>
Reactの場合
Reactでは、useState
から得たsetCount
関数を使って状態を更新します。
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
function increment() {
setCount(count + 1);
}
return <div>Count: {count}</div>;
}
export default Counter;
2. ライフサイクル(onMounted
とuseEffect
、onUnmounted
)
VueのonMounted
とReactのuseEffect
は、コンポーネントのライフサイクルに関わる処理を記述するためのものです。
たとえば、外部APIのデータ取得や、初期化処理などに使われます。
さらに、VueのonUnmounted
に相当するReactの機能として、useEffect
内で「クリーンアップ関数(戻り値の関数)」を使います。
例:マウントとアンマウント時の処理
Vueの場合
onMounted
でマウント時の処理を行い、onUnmounted
でアンマウント時の処理を追加します。
<script setup>
import { onMounted, onUnmounted } from 'vue';
onMounted(() => {
console.log('コンポーネントがマウントされました!');
});
onUnmounted(() => {
console.log('コンポーネントがアンマウントされました!');
});
</script>
Reactの場合
Reactでは、useEffect
の戻り値にクリーンアップ関数を記述します。
import { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
console.log('コンポーネントがマウントされました!');
return () => {
console.log('コンポーネントがアンマウントされました!');
};
}, []);
return <div>こんにちは!</div>;
}
export default MyComponent;
3. 状態の監視(watch
とuseEffect
)
Vueのwatch
は特定の状態やプロパティの変更(監視したいref
)を監視して、必要な処理を行います。
Reactでは、useEffect
に依存配列(監視したいstate
)を指定することで似たような監視を実現できます。
例:監視対象が変わるたびにログを出力
Vueの場合
watch
を使い、状態が変化したときの処理を記述します。
<script setup>
import { ref, watch } from 'vue';
const message = ref('Hello');
watch(message, (newValue, oldValue) => {
console.log(`変更前: ${oldValue}, 変更後: ${newValue}`);
});
</script>
Reactの場合
Reactでは、useEffect
の依存配列に状態を渡します。
import { useState, useEffect } from 'react';
function WatchComponent() {
const [message, setMessage] = useState('Hello');
useEffect(() => {
console.log(`メッセージが変更されました: ${message}`);
}, [message]);
return (
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="メッセージを入力してください"
/>
);
}
export default WatchComponent;
4. グローバル状態管理(PiniaとRedux)
VueではPinia
が主流の状態管理ライブラリとして使われますが、ReactではRedux
が広く採用されています。
どちらも複雑なアプリケーションで複数のコンポーネント間の状態を一元管理するのに便利です。
Piniaの特徴
- Vue 3用に設計されており、シンプルで直感的なAPIを提供
- TypeScriptとの統合が簡単
Reduxの特徴
- 状態管理のための厳密なルールを提供
- ミドルウェアを使って高度な拡張が可能
VueとReactで異なるところ
次に、VueとReactで異なる特徴を具体例とともに解説します。
1. 記述スタイル(HTMLライクとJSライク)
VueはHTMLに拡張的にJavaScriptを追加するスタイルですが、ReactはJavaScriptを中心に記述します。
Vueはテンプレート内にスクリプトを埋め込みますが、Reactはコンポーネント全体を関数内で構築するスタイルです。
例:コンポーネントの記述
Vueの場合
<template>
<button @click="handleClick">クリックしてください</button>
</template>
<script setup>
function handleClick() {
alert('クリックされました!');
}
</script>
Reactの場合
function MyComponent() {
function handleClick() {
alert('クリックされました!');
}
return <button onClick={handleClick}>クリックしてください</button>;
}
export default MyComponent;
2. 状態更新の方法
Vueでは状態を直接更新しますが、Reactでは専用の関数を使用して状態を更新します。
この違いは、Reactが「イミュータブル(不変)」なデータ管理を重視している点に起因します。
例:カウントを10に更新
Vueの場合
状態を直接更新できます。
<script setup>
import { ref } from 'vue';
const count = ref(0);
function updateCount() {
count.value = 10;
}
</script>
Reactの場合
更新専用の関数setCount
を使用します。
import { useState } from 'react';
function UpdateCount() {
const [count, setCount] = useState(0);
function updateCount() {
setCount(10);
}
return <div>カウント: {count}</div>;
}
export default UpdateCount;
オブジェクトの場合
Reactではオブジェクトを更新する際に新しいオブジェクトを作成する必要があります。
import { useState } from 'react';
function UpdateObject() {
const [fruit, setFruit] = useState({ name: 'banana', price: 200 });
function updatePrice() {
setFruit({ ...fruit, price: 400 });
}
return (
<div>
{fruit.name}: {fruit.price}
<button onClick={updatePrice}>価格を更新</button>
</div>
);
}
export default UpdateObject;
3. 子から親へのデータ受け渡し
Vueではemit
で親コンポーネントにイベントを発火して値を渡します。
一方、Reactでは親コンポーネントから関数を渡し、それを子コンポーネントで実行して値を渡します。
例:子コンポーネントから親にメッセージを送る
Vueの場合
<!-- Parent.vue -->
<template>
<Child @send-message="handleMessage" />
<div>{{ message }}</div>
</template>
<script setup>
import { ref } from 'vue';
const message = ref('');
function handleMessage(msg) {
message.value = msg;
}
</script>
<!-- Child.vue -->
<template>
<button @click="$emit('send-message', 'こんにちは!')">送信</button>
</template>
Reactの場合
function Parent() {
const [message, setMessage] = useState('');
return (
<div>
<Child onMessage={setMessage} />
<div>{message}</div>
</div>
);
}
function Child({ onMessage }) {
return <button onClick={() => onMessage('こんにちは!')}>送信</button>;
}
export default Parent;
感想
Reactの方が難しいと言われるけど、そんなことないです!
どちらも難しいです!笑
でもVueの経験がある方にとって、Reactの学習はスムーズに進むと思いました。
Reactは大規模開発に向いていると言われますが、コンポーネントごとのデータの流れが単一なのことと、規約が結構はっきりしているので、他の開発者から見てもコードが理解しやすいと思いました。
特にReactの「関数型プログラミング」は独特で、縛りはあるものの、コードの構造化や再利用性は高いと感じましました。
逆に言うと、Reactの方が関数型プログラミングの思想が強く、良くも悪くも構造化を考えないといけないので、そこまで設計を考慮しないのであればVueでもいいと思いました。
ただ両者似ており、どっちも正直同じ設計思想で扱うことができます。
フロントエンドの本質的なスキルは、共通しているなと感じました。
ライフサイクルを考えて描画したり、コンポーネントの設計をしっかり考えて切りだしたり、型定義したりと、、
React楽しい!
(Vueが廃れそうなのはありそうですので、両方できる用勉強しておきます。。)