2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VueのComposition APIとReact Hooksは何が似ていて何が違うのか

2
Posted at

はじめに

この記事では、Vue の Composition API と React Hooks の違いを整理します。

Vue 3 と React は、どちらも関数ベースでロジックを組み立てる感覚があります。
そのため、Composition API と Hooks は似て見えます。

実際、次のような共通点があります。

  • 状態を持てる
  • ロジックを分割できる
  • 関心ごとごとにまとめやすい

ただし、似ているのは表面だけで、使っていて感じる書き味はかなり違います。

先に結論

先に結論を書くと、次の違いです。

  • Vue の Composition API は reactivity の仕組みが前面にある
  • React Hooks は render と state 更新の仕組みが前面にある

つまり、

  • Vue は「リアクティブな値を組み立てる」感覚
  • React は「再レンダリングされる関数の中で state を扱う」感覚

です。

似ているところ

まず、似ているところから見ます。

Vue:

import { ref } from "vue";

const count = ref(0);

const increment = () => {
  count.value++;
};

React:

import { useState } from "react";

const [count, setCount] = useState(0);

const increment = () => setCount((count) => count + 1);

どちらも、

  • 状態を持つ
  • 更新関数を書く
  • UI に反映される

という意味では近いです。

Vueはrefやreactiveが中心になる

Vue の Composition API では refreactive が中心です。

const name = ref("名無し");
const form = reactive({
  email: "",
  age: 0,
});

Vue では「リアクティブな値」を先に作る感覚が強いです。

そのため、ロジックを読んでいても、

  • この値は reactive か
  • ref
  • computed

のように、リアクティブシステムの種類を意識する場面が多いです。

Reactはstateとrenderの関係が中心になる

React では useState を中心に state を扱い、必要なときだけ useEffect で外部同期を扱います。

const [name, setName] = useState("名無し");

React で意識するのは、次の流れです。

  • state が変わる
  • コンポーネントが再レンダリングされる
  • JSX が再評価される

Vue より「再レンダリングされる関数」という感覚が強いです。

computed と useMemo は似て見えるが同じではない

Vue の computed と React の useMemo は似て見えますが、感覚は違います。

Vue:

const fullName = computed(() => `${firstName.value} ${lastName.value}`);

React:

const fullName = useMemo(() => `${firstName} ${lastName}`, [firstName, lastName]);

useMemo は、値の再計算結果をメモしておき、依存配列の中の値が変わったときだけ再計算するためのフックです。
そのため、毎回の render で重い計算をやり直したくないときや、参照の安定性を保ちたいときに使います。
React では、派生値はまず render 中にそのまま計算し、重さや参照安定性が問題になるときに useMemo を検討する形が基本です。

Vue の computed は、リアクティブな値から派生値を作る自然な流れです。
React の useMemo は、再計算コストや参照安定性を意識した最適化の文脈が混ざります。

そのため、React では computed のような気軽さで useMemo を増やすと、かえって読みにくくなることがあります。

watch と useEffect も発想が違う

Vue:

watch(searchWord, () => {
  fetchList();
});

React:

useEffect(() => {
  fetchList();
}, [searchWord]);

見た目は近いですが、ここも発想が違います。

  • Vue の watch は値の変化を監視する
  • React の useEffect はレンダー後の副作用を扱う

Vue の watch は「この値が変わったらこの処理を動かす」という読み方をしやすいです。
一方で React の useEffect は、単純な監視フックとして使うより、外部システムと同期する境界として考えた方が実態に近いです。

React では、render 中に計算できることや、イベントハンドラで直接処理できることまで useEffect に入れると、かえって回りくどくなりやすいです。
そのため useEffect は「値が変わったら何かする便利フック」というより、「render の外にあるものとつなぐ場所」と捉えた方が整理しやすいです。

React の useEffect は便利ですが、慣れるまでは「これは監視なのか、副作用なのか、初回実行なのか」で混乱しやすいです。

この点では、Vue の watch のほうが意図が分かりやすい場面もあります。

Reactのほうが分かりやすいと感じるのはどこか

それでも React のほうが分かりやすいと感じる人は多いです。
理由は、最終的に JavaScript の関数として追いやすいからです。

  • state は useState
  • 更新は setState
  • 副作用は useEffect
  • UI は JSX

Vue は便利ですが、ref reactive computed watch など、リアクティブシステム側の概念が少し厚めです。

React はフックのルールを覚える必要はありますが、慣れると「この関数コンポーネントの中で何が起きるか」を追いやすいです。

まとめ

Vue の Composition API と React Hooks は、どちらも関数ベースでロジックを組み立てられます。

ただし、中心にある考え方は違います。

  1. Vue は reactivity 中心
  2. React は render と state 更新中心
  3. computeduseMemo は似て見えても役割の重さが違う
  4. watchuseEffect も発想は同じではない

そのため、React のほうが分かりやすいと感じるなら、それは Hooks が「JavaScript の関数と state 更新」として追いやすいからです。
Vue のほうが自然に感じるなら、それは reactivity の抽象化がうまく効いているからです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?