SyntaxStudy
Sign Up
Vue.js Beginner 1 min read

storeToRefs and $patch

Destructuring a Pinia store directly breaks reactivity because you're pulling plain values off the object. The solution is `storeToRefs(store)`, which returns a refs version of every state property and getter, suitable for destructuring. Actions are plain functions and don't need `storeToRefs` treatment — destructure them directly from the store. `$patch` allows batch state mutations using either a partial state object or a mutator callback. The object form is ideal for simple multi-field updates; the callback form gives you the full state object and is better for updates that depend on current values, such as toggling a boolean or pushing to an array. Batch mutations are applied atomically and trigger only a single reactivity update. Pinia devtools integration lets you inspect the current state of all stores, travel through history of mutations, and even import/export store state snapshots. In production you can use the `$state` property to access or replace the entire state object, or call `$reset()` on Options API stores (setup-function stores need a manual reset action).
Example
<script setup>
import { storeToRefs }     from 'pinia';
import { useCounterStore } from '@/stores/counter';
import { useUserStore }    from '@/stores/user';

const counterStore = useCounterStore();
const userStore    = useUserStore();

// ── storeToRefs: reactive destructure ─────────
const { count, doubled, step } = storeToRefs(counterStore);
// Actions destructured directly (no storeToRefs needed)
const { increment, reset } = counterStore;

// ── $patch: batch update ──────────────────────
userStore.$patch({ name: 'Alice', age: 31 });

// $patch with callback (depends on current state)
counterStore.$patch((state) => {
  state.count += 10;
  state.step   = 2;
});

// ── Subscribe to store changes ─────────────────
counterStore.$subscribe((mutation, state) => {
  localStorage.setItem('counter', JSON.stringify(state));
});
</script>

<template>
  <p>Count: {{ count }} | Doubled: {{ doubled }} | Step: {{ step }}</p>
  <button @click="increment">+{{ step }}</button>
  <button @click="reset">Reset</button>
</template>