## 事象
以下のように[[Pinia]]で生成したStoreを[[分割代入 (JavaScript)|分割代入]]すると、データが[[リアクティブ]]ではなくなってしまう。`+`ボタンをクリックしてもカウントが増えない。
`stores/counter.ts`
```ts
import { defineStore } from "pinia";
import { ref } from "vue";
export const useCounterStore = defineStore("counter", () => {
const count = ref(0);
function increment() {
count.value++;
}
return { count, increment };
});
```
```html
<script setup lang="ts">
import { useCounterStore } from "./stores/counter";
const { count, increment } = useCounterStore();
</script>
<template>
<h1>Hello</h1>
<div>{{ count }}</div>
<button @click="increment">+</button>
</template>
```
なお、[[Composable]]を使った場合は[[リアクティブ]]である。
`composables/useCounter.ts`
```ts
import { ref } from "vue";
export function useCounter() {
const count = ref(0);
const increment = () => {
count.value++;
};
return { count, increment };
}
```
`App.vue`
```html
<script setup lang="ts">
import { useCounter } from "./composables/useCounter";
const { count, increment } = useCounter();
</script>
<template>
<h1>Hello</h1>
<div>{{ count }}</div>
<button @click="increment">+</button>
</template>
```
## 原因
直接[[リアクティブ]]な値 (`ref(...)`) を返却する[[Composable]]とは異なり、[[Pinia]]では`defineStore`を通じた返却を行うため。
## 解決方法
方法は2通りある。個人的には1つ目の方法が好き。『storeは分割代入しない』というルールさえ守っておけば、予期せぬ実行時不具合を回避できるため。
### 分割代入を使用しない
[[分割代入 (JavaScript)|分割代入]]を使わなければ当然問題は解決する。こだわりがない場合は一番確実。
```html
<script setup lang="ts">
import { useCounterStore } from "./stores/counter";
const counterStore = useCounterStore();
</script>
<template>
<h1>Hello</h1>
<div>{{ counterStore.count }}</div>
<button @click="counterStore.increment">+</button>
</template>
```
### storeToRefsを使う
公式ドキュメントに案内されている`storeToRefs`でstoreを包んであげる。
<div class="link-card">
<div class="link-card-header">
<img src="https://pinia.vuejs.org/logo.svg" class="link-card-site-icon"/>
<span class="link-card-site-name">pinia.vuejs.org</span>
</div>
<div class="link-card-body">
<div class="link-card-content">
<p class="link-card-title">Defining a Store | Pinia</p>
<p class="link-card-description">Intuitive, type safe, light and flexible Store for Vue</p>
</div>
</div>
<a href="https://pinia.vuejs.org/core-concepts/#Destructuring-from-a-Store"></a>
</div>
```html
<script setup lang="ts">
import { storeToRefs } from "pinia";
import { useCounterStore } from "./stores/counter";
const s = useCounterStore();
const { count } = storeToRefs(s);
const { increment } = s;
</script>
<template>
<h1>Hello</h1>
<div>{{ count }}</div>
<button @click="increment">+</button>
</template>
```