40
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Vue3】refとreactiveで管理できるものを理解していなかった話

Posted at

はじめに

コードを書く中で「あれ?これってref、reactiveどっちで定義すればいいんだ?オブジェクトだからreactive?」ということがあり、何も理解していなかったので備忘録として残したいと思います。(理解したとは言っていない)
以下認識誤り等ありましたら、ご指摘いただけると幸いです🙇‍♂

環境

  • Vue3 , Nuxt3
    • Composition API
  • TypeScript

結論

オブジェクトだからといって、必ずしもreactiveで定義する必要はない(refでもOK)

勘違いしていたこと

学習する中で、何故かref=プリミティブreactive=オブジェクトと思い込んでおり、「オブジェクトを定義するときはreactiveで定義しなきゃ」という思考になっていました。
reactiveがプリミティブNGなだけで、refは何でもOKでした。

プリミティブ=ざっくり、オブジェクト以外の文字列や数値などのこと

プリミティブ オブジェクト
ref
reactive

プリミティブ

<script setup lang="ts">
// reactiveは使えない
let refCount = ref(0);
let reactiveCount = reactive(0); //NG
</script>

オブジェクト

<script setup lang="ts">
// ref, reactiveどちらでもOK
let refUser = ref({
  name: "Ref",
  age: 20,
});

let reactiveUser = reactive({
  name: "Reactive",
  age: 30,
});
</script>

ref, reactiveどちらを使うか

細かい説明は割愛しますが、いろいろな方の意見を総合すると、とりあえずrefでよさそうです。(参考参照)
個人的にも、オブジェクト全体を更新する際にreactiveだとプロパティ別に更新する必要があるので、refでいいかなと思っています。

オブジェクト全体を更新する例

<template>
  <div>
    名前:{{ refUser.name }}&nbsp;年齢:{{ refUser.age }}
  </div>
  <div>
    名前:{{ reactiveUser.name }}&nbsp;年齢:{{ reactiveUser.age }}
  </div>
  <div>
    <button @click="refIncrement">RefAge+</button>
  </div>
  <div>
    <button @click="reactiveIncrement">ReactiveAge+</button>
  </div>
  <button @click="allChange">allChange</button>
</template>
<script setup lang="ts">
let refUser = ref({
  name: "Ref",
  age: 20,
});

let reactiveUser = reactive({
  name: "Reactive",
  age: 30,
});

const refIncrement = () => {
  refUser.value.age++;
};

const reactiveIncrement = () => {
  reactiveUser.age++;
};

const allChange = () => {
  // refだと一括更新できる
  refUser.value = {
    name: "Ref Taro",
    age: 40,
  };

  // reactiveで下記はNG(リアクティブなオブジェクトではなくなる)
  reactiveUser = {
    name: "Reactive Taro",
    age: 60,
  };

  // 下記のように個別更新であればOK
  // reactiveUser.name = "Reactive Taro";
  // reactiveUser.age = 60;
};
</script>

まとめ

  • reactiveではプリミティブがNG
  • オブジェクトを扱う際はref, reactiveどちらでも問題ない(個人的にはref)

参考

40
9
1

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
40
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?