Vue3のrefとreactiveの違い

今日はVue3 の分かったようでわからないref()とreactive()の違いを説明します。

Vue3のref()とは

Vue3のrefは、Vue.jsフレームワークで導入されたリアクティブなデータを扱うための機能です。refは、単一の値をラップし、それを監視して変更があった場合に自動的に再レンダリングすることができます。

refを使用すると、リアクティブなデータを簡単に作成できます。通常、基本データ型(文字列、数値、真偽値など)をrefでラップします。例えば、以下のようにrefを使用して数値を定義できます。

import { ref } from 'vue';

const count = ref(0);


このコードでは、ref関数を使ってcountというリアクティブなデータを定義しています。初期値として0を渡しています。

refでラップされたデータを参照する場合は、.valueプロパティを使用します。

console.log(count.value); // 0


データを変更する場合は、単純に新しい値を代入します。Vueは自動的に変更を検出し、再レンダリングをトリガーします。

count.value = 1;
console.log(count.value); // 1


refは、単一の値だけでなく、オブジェクトや配列などのデータ構造もラップすることができます。ただし、ネストしたプロパティの変更を検出するためには、.valueを明示的に使用する必要があります。

const data = ref({ name: 'John', age: 25 });
console.log(data.value.name); // 'John'

data.value.name = 'Jane';
console.log(data.value.name); // 'Jane'


また、refはVueコンポーネント内で使用されることが一般的です。リアクティブなデータを使用することで、コンポーネントの状態の変更を監視し、自動的に再レンダリングすることができます。

reactive()とは

Vue3のreactiveは、Vue.jsフレームワークで使用されるリアクティブなオブジェクトを作成するための関数です。reactiveを使用すると、オブジェクトをリアクティブに監視し、そのプロパティの変更を検出して自動的に再レンダリングすることができます。

reactiveを使ってリアクティブなオブジェクトを作成するには、reactive関数にオブジェクトを渡します。以下はその例です。

import { reactive } from 'vue';

const state = reactive({
  count: 0,
  name: 'John'
});


このコードでは、reactive関数を使ってstateというリアクティブなオブジェクトを作成しています。stateオブジェクトは、countnameという2つのプロパティを持っています。

リアクティブなオブジェクトのプロパティにアクセスするには、通常のJavaScriptオブジェクトのようにドット記法やブラケット記法を使用します。

console.log(state.count); // 0
console.log(state.name); // 'John'


stateオブジェクトのプロパティを変更すると、Vueは変更を検出し、関連するコンポーネントの再レンダリングをトリガーします。

state.count = 1;
console.log(state.count); // 1


reactiveを使用すると、ネストされたオブジェクトや配列もリアクティブにすることができます。ただし、ネストされたプロパティにアクセスする場合は、リアクティブオブジェクトの参照を使用する必要があります。

state.nested = reactive({ prop: 'Nested Property' });
console.log(state.nested.prop); // 'Nested Property'

state.nested.prop = 'Updated Property';
console.log(state.nested.prop); // 'Updated Property'


reactiveを使用することで、Vueコンポーネント内でリアクティブなデータを簡単に管理できます。プロパティの変更を追跡し、自動的に再レンダリングすることで、アプリケーションの状態を効果的に管理することができます。

refでオブジェクトを格納できるのにわざわざreactiveを使う理由

refを使用してオブジェクトを格納することはできますが、reactiveを使う理由はいくつかあります。

  1. プロパティの自動追跡: refでオブジェクトを格納する場合、オブジェクトのプロパティが変更されると、そのプロパティにアクセスするたびに.valueを明示的に使用する必要があります。一方、reactiveを使用すると、オブジェクト全体がリアクティブになり、プロパティの変更を自動的に検知して再レンダリングをトリガーします。これにより、より直感的にオブジェクトのプロパティを使用できます。
  2. ネストされたオブジェクトや配列のリアクティブな扱い: refを使用してオブジェクトをラップする場合、ネストされたオブジェクトや配列のプロパティの変更を追跡するために、各プロパティに対して個別にrefを使用する必要があります。一方、reactiveはオブジェクト全体をリアクティブに扱うため、ネストされたオブジェクトや配列の変更も自動的に検知できます。
  3. コードの簡潔さと可読性: reactiveを使用すると、オブジェクトを一括でリアクティブに扱えます。プロパティへのアクセスが簡潔になり、.valueを使う必要がないため、コードの可読性が向上します。

ただし、refを使用してオブジェクトを格納する場合でも、ユーティリティ関数であるtoRefsを使用することで、オブジェクトのプロパティをリアクティブに扱うことができます。これにより、refreactiveを組み合わせた使い方が可能になります。

短いコードや単純なデータ構造の場合には、refでオブジェクトを格納するだけで十分です。しかし、より複雑なデータ構造やネストされたオブジェクトを扱う場合には、reactiveを使用することでコードの可読性とメンテナンス性が向上するでしょう。

reactive(null)がエラーになる理由

reactive(null)がエラーになる理由は、reactive関数はオブジェクトを引数として受け取る必要があるためです。nullはオブジェクトではなく、プリミティブ型の一種です。

reactive関数は、与えられたオブジェクトをリアクティブにラップし、そのプロパティの変更を検知するために内部的なトラッキング機構を使用します。しかし、nullはオブジェクトではないため、トラッキングするプロパティが存在しないためエラーが発生します。

もし、nullをリアクティブに扱いたい場合は、refを使用することが適切です。refはプリミティブ型やオブジェクトの両方をラップすることができます。