Svelte 5: Runes с useOptimistic и Zustand для оптимистичных уведомлений
-
В Svelte 5 руны меняют правила игры для стейта. Теперь с $state, $derived и $effect можно делать оптимистичные обновления уведомлений без лагов и лишнего рендера. Это решает боль медленных сетевых запросов - UI реагирует мгновенно, а откат при ошибке автоматический.
Zustand как стейт-менеджер идеально вписывается в эту схему. Комбинируем руны с useOptimistic-подобным паттерном, и получаем киллер-фича для уведомлений: добавляем уведомление сразу, шлем на сервер, при фейле - роллбэк. DX на высоте, бандл лёгкий, Web Vitals в зелёной зоне.
Почему руны в Svelte 5 - это будущее стейта
Руны в Svelte 5 - это сигналы под капотом, мелкозернистая реактивность без бойлерплейта. Забудьте про старый реактивный let, теперь $state создаёт чистый сигнал, который триггерит обновления только там, где нужно. Для уведомлений это идеально: список сообщений обновляется точечно, без полного ререндера компонента.
Представьте: юзер шлёт уведомление, UI показывает его мгновенно с ‘отправка…’. Сервер отвечает - метка уходит, или при ошибке уведомление откатывается. Без рун пришлось бы мутировать массив вручную и следить за состоянием. С рунами и Zustand всё чисто: стейт иммутабельный, обновления предсказуемые. Это не просто фича - это оп��имизация производительности на уровне Solid.js.
- $state для базового стейта:
let notifications = $state([]);- массив уведомлений реактивный из коробки. - $derived для вычислений:
const pendingCount = $derived(notifications.filter(n => n.status === 'pending').length);- счётчик пендингов без лишних эффектов. - $effect для сайд-эффектов:
$effect(() => { if (notifications.length > 50) notifications.shift(); });- автоочистка старых сообщений.
Аспект Старый Svelte Runes в Svelte 5 Реактивность Глобальный трекинг Мелкозернистая, сигналы Бойлерплейт export let $props(), $state() Оптимизации Компилятор + Иммутабельность, точечный рендер Нюанс: руны работают и в .svelte, и в .js/.ts файлах - портируем стейт в Zustand без боли.
Zustand + руны: глобальный стейт без Redux-кошмара
Zustand - лёгкая либа для стейта, без провайдеров и контекста. В Svelte 5 она идеально комбинируется с рунами: создаём стор с $state внутри, экспортируем хуки. Для уведомлений это win: один стор на все компоненты, атомарные обновления, никаких пропс-дриллов.
Стор выглядит так:
const useNotificationsStore = create((set) => ({ notifications: $state([]), addOptimistic: (notif) => set((state) => { state.notifications.unshift({ ...notif, status: 'pending' }); }) }));. Здесь addOptimistic - наш аналог React-хука, мутирует стейт оптимистично. Затем асинхронно шлём на API, при успехе обновляем статус, при ошибке - фильтруем из массива. Реактивность рун подхватывает изменения автоматически.- Инициализация стора: Импортируем Zustand, оборачиваем в $state для реактивности.
- Оптимистичный адд: Добавляем в начало списка с pending статусом.
- Асинхронный апдейт: fetch/post, затем set с реальным статусом или удалением.
const useNotificationsStore = create((set, get) => ({ notifications: $state([]), addOptimistic: async (text: string) => { const id = Date.now(); set((state) => { state.notifications.unshift({ id, text, status: 'pending' }); }); try { await fetch('/api/notifications', { method: 'POST', body: JSON.stringify({ text }) }); set((state) => { const idx = state.notifications.findIndex(n => n.id === id); if (idx > -1) state.notifications[idx].status = 'sent'; }); } catch { set((state) => state.notifications = state.notifications.filter(n => n.id !== id)); } } }));Красота кода: Zustand не навязывает редьюсеры, руны обеспечивают гранулярные обновления. Бандл растёт минимально - Zustand всего 1кб.
useOptimistic паттерн в Svelte: реализация на рунах
useOptimistic из React - хук для мгновенных UI-обновлений во время async. В Svelte 5 нет нативного, но с рунами и Zustand патчим сами. Логика: держим два слоя стейта - optimistic (с pending) и confirmed (с сервера). $derived сливает их в один список для рендера.
Пример в компоненте:
function handleSend() { useNotificationsStore.getState().addOptimistic(inputValue); }. UI показывает pending сразу, эффект в сторе обрабатывает откат. Это даёт отзывчивость как в Gmail - уведомление появляется до API-ответа. При ошибке роллбэк плавный, без мерцания.- Преимущества: Задержка воспринимается как 0мс, LCP/INP в топе Web Vitals.
- Ловушки: Всегда валидируй на сервере - клиент optimistic.
- Расширение: Добавь $effect для WebSocket-реалтайм синка.
Сценарий Без optimistic С useOptimistic Add уведомления Ждёт API (500мс+) Мгновенно + откат Рендер Полный ререндер Точечный Ошибка Пустой список Авто-роллбэк Собираем пазл: уведомления с SSR и рунами
Для SSR в SvelteKit гидратируем стейт из Zustand - руны поддерживают серверный рендер из коробки. В +page.svelte:
let { notifications } = useNotificationsStore();. При гидратации optimistic-логика работает seamless, без hydration mismatch.Код компонента уведомлений: простая таблица или список с {notifications.map(n =>
{n.text})}. Стилизуем pending как скелетон - юзер кайфует от скорости. Масштабируй на тысячи уведомлений - производительность не страдает.Такой подход меняет DX в Svelte
Руны + Zustand + optimistic - комбо для уведомлений, которое масштабируется на чат, туду, дашборды. Осталось за кадром: интеграция с TanStack Query для кэша, или кастомные $effect для оффлайн-режима. Подумай, как это впишется в твой стэк - бандл полетит, а юзеры скажут спасибо за скорость.
- $state для базового стейта:
Здравствуйте! Похоже, вас заинтересовала эта беседа, но у вас ещё нет аккаунта.
Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.
С вашими комментариями этот пост мог бы стать ещё лучше 💗
Зарегистрироваться Войти© 2024 - 2026 ExLends, Inc. Все права защищены.