Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чому деструктуризація стору Pinia ламає реактивність і що робить storeToRefs?

Стор Pinia - об'єкт, обгорнутий у reactive(). Звичайна деструктуризація копіює поточні значення в локальні змінні - і зв'язок з реактивністю зникає:

const cart = useCartStore();
const { items, total } = cart;   // items і total більше не оновлюються

Після cart.add(product) в інтерфейсі нічого не зміниться: total лишився числом, обчисленим у момент деструктуризації.

storeToRefs() перетворює стан і гетери на ref, що лишаються пов'язаними зі стором:

import { storeToRefs } from 'pinia';

const cart = useCartStore();
const { items, total } = storeToRefs(cart);   // реактивні ref
const { add, clear } = cart;                  // дії - звичайною деструктуризацією
<template>
  <p>Разом: {{ total }} грн</p>   <!-- оновлюється -->
</template>

Чому дії деструктурують без storeToRefs: це звичайні функції, прив'язані до стору. storeToRefs() їх пропускає - він повертає лише стан і гетери.

Що ще варто знати:

  • у скрипті значення з storeToRefs - це ref: total.value, у шаблоні - просто total;
  • зміна items.value = [] змінює стан стору, а не локальну копію - це двосторонній зв'язок;
  • toRefs() з Vue на сторі теж «працює», але перетворює на ref і дії, і внутрішні властивості - для сторів потрібен саме storeToRefs();
  • найпростіший варіант без пасток - не деструктурувати взагалі й звертатися через cart.total.

Та сама проблема виникає з reactive() і з props у компонентах: деструктуризація реактивного об'єкта завжди «знімає копію».

Докладніше в документації: Pinia: деструктуризація стору

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання