🏪 Global State vs Local State: когда глобальное хранилище — это overkill
В разработке часто встречаю паттерн: создают глобальный store для данных, которые используются в одном месте. Разберем, когда это оправдано, а когда — избыточно.
Что такое глобальный store?
Это состояние, живущее на уровне всего приложения. Обновил данные в одном компоненте — они актуальны везде. Классический пример: информация о пользователе (токен, email, имя) — singleton на всю систему.
Когда глобальный store оправдан?
✅ Данные используются в нескольких местах ✅ Должны быть одинаковыми везде ✅ Изменения нужно синхронизировать ✅ Логика работы с данными инкапсулирована
Примеры: useAuthStore(), useCurrentUserStore(), useThemeStore()
Цена глобального состояния
Store — не бесплатная штука. Вот что получаете в нагрузку:
1. Ручная синхронизация Создали сущность → обновить store Удалили сущность → обновить store Отредактировали → обновить store
Пропустили хоть один случай — state устарел.
2. Проблемы многопользовательских приложений // Пользователь А: удалил элемент, store обновлен await deleteItem(id) items.value = items.value.filter(i => i.id !== id)
// Пользователь Б: тоже удалил элемент через 2 минуты // Пользователь А об этом НЕ знает (нет WebSocket/SSE)
// Пользователь А открывает список через 5 минут // Store показывает 2 элемента, на сервере их 1 // Попытка использовать удаленный элемент → ошибка 404
Без real-time коммуникации между клиентами store становится источником багов.
3. Cache invalidation Одна из сложнейших проблем, когда инвалидировать store? - Каждую минуту? - При каждом монтировании компонента? - При фокусе на вкладке? - При возврате на страницу?
Нет универсального ответа — только трейдоффы.
Альтернатива: локальное состояние // В компоненте const items = ref([])
const fetchItems = async () => { items.value = await getItems() }
// Запрашиваем когда нужно onMounted(() => fetchItems()) // Или при открытии dropdown // Или по клику на кнопку
Что получили:
✅ Всегда актуальные данные ✅ Не думаем о синхронизации ✅ Нет race conditions между пользователями ✅ Проще понять и поддерживать ✅ Меньше связанности (coupling)
Пример: список для dropdown // ❌ Overkill: глобальный store const categoriesStore = ref([])
export function useCategoriesStore() { const getAll = async () => { categoriesStore.value = await fetchCategories() } return { categories: categoriesStore, getAll } }
// Используется только в одной форме // Нужна синхронизация при CRUD // Может устареть в многопользовательской среде
// ✅ Просто и работает: локальное состояние const categories = ref([])
const loadCategories = async () => { categories.value = await fetchCategories() }
// Запрашиваем при открытии @dropdown-open="loadCategories"
Когда НЕ нужен global store?
❌ Данные используются локально (одна форма/компонент) ❌ Актуальность важнее кэширования ❌ Нет сложной бизнес-логики вокруг данных ❌ Многопользовательская среда без real-time sync ❌ Данные быстро меняются Вывод
Глобальный store — мощный инструмент, но не панацея.
Правило: Используй самое простое решение, которое работает. Усложняй только когда появляется реальная потребность.
Не стройте архитектуру "на вырост" — YAGNI (You Aren't Gonna Need It).
Чеклист выбора Использовать global store: - Данные в 3+ компонентах - Нужна единая точка истины - Есть сложная логика управления - Real-time синхронизация между клиентами
Использовать local state: - Данные в 1-2 компонентах - Важна актуальность - Простая логика загрузки - Нет real-time инфраструктуры
Золотое правило: Начинай с локального состояния. Рефактори в global store, когда появится боль от дублирования.
Сталкивались с проблемами из-за избыточного использования глобального состояния? 💬
#vue #architecture #statemanagement #frontend #bestpractices