reactive()の落とし穴
事例
フォームの値を保持するのにVue Composition APIを使い、フェッチしてきた値を初期値として設定したい。
ref() は Primitive な値に用い、 reactive() は Object を入れるのに使うのかな?と思い、後者を利用した。
code:js
const form = reactive({
email: '',
password: '',
})
useFetch(async () => {
const data = await fetch()
form.email = data.email
form.password = data.password
})
return { form }
結果
フォームの各プロパティの値がうまく書き換わらなかった。
(実際にはフォームは子コンポーネントだったが、値が書き換わっていたりそうでなかったり変な挙動を示した)
原因と対策
reactive() に含まれるオブジェクトは、それ全体としてのみリアクティブである。つまり、
個別のプロパティについて値を書き換えることができない。
プロパティから取り出した値はリアクティブでなくなる。
事例では、個別に値が変わりうるフォームを reactive() として置いたのがそもそも不適切だった。
この場合、 toRefs() というのを噛ませてプロパティを個別に reactive な要素にする必要がある。
code:js
return { toRefs(form) }
Vue の思想的には Object を丸ごと reactive にするべきではないのかもしれない。
しかし上のようなことをしなくても ref() で結局 reactive にできてしまうので、reactive() はわざわざ使わなくてよいのでは。
code:js
const form = ref({
email: '',
password: '',
})
(そもそも reactive() はそうやって使うものじゃないとかあったら教えてください)