State Management

Svelte: руны и stores

Svelte-команда пишет редактор маршрутов для службы доставки. Внутри одного компонента карты состояние выражено руной `$state`: точки маршрута, выбранный курьер, режим редактирования. Но статус смены курьера нужен и в шапке, и в боковой панели, и в модалке подтверждения. Локальная руна туда не дотянется. Тогда состояние выносится в store: writable-значение, на которое подписываются все три несвязанных компонента. Svelte даёт два уровня: руны для локального реактивного состояния и stores для общего.

  • Локальное состояние компонента: режим формы, открытый аккордеон, текущий шаг визарда через $state
  • Производные значения через $derived: итоговая сумма корзины, валидность формы, число выбранных строк
  • Общее состояние между несвязанными компонентами через writable store: тема, текущий пользователь, тосты
  • Команды на SvelteKit, разделяющие состояние страницы и глобальные stores приложения
  • Интеграция store с внешними источниками: WebSocket-поток в readable store с подпиской

Предварительные знания

  • Идея observable: значение, на изменения которого можно подписаться
  • Понимание реактивности: при изменении источника зависимые значения пересчитываются
  • Различие между локальным состоянием компонента и общим состоянием приложения
  • Observable и Proxy

Руны: реактивное состояние компонента

Svelte 5 вводит руны - специальные функции-маркеры, которые сообщают компилятору о реактивности. Руна `$state` объявляет реактивное значение: его изменение точечно обновляет ту часть DOM, что от него зависит. В отличие от React, реактивность не требует хука и массива зависимостей - компилятор сам строит граф зависимостей на этапе сборки.

Руна `$derived` объявляет производное значение: doubled пересчитывается всякий раз, когда меняется count, без ручного указания зависимостей. Компилятор видит, что doubled читает count, и связывает их. Это наблюдаемая реактивность из прошлого урока, но встроенная в язык шаблона и оптимизированная на этапе компиляции.

Руны появились в Svelte 5 (релиз конца 2024 года). До них реактивность держалась на присваивании let и метке `$:`, что путало новичков. Руны сделали реактивное состояние явным: `$state` и `$derived` читаются как маркеры намерения.

Что делает руна `$state` в Svelte 5?

Stores: общее состояние

Руна `$state` живёт внутри одного компонента. Когда состояние нужно нескольким несвязанным компонентам, Svelte предлагает stores. Store это наблюдаемое значение с методами subscribe, set и update. writable создаёт изменяемый store, readable - доступный только для чтения, например обёртку над внешним источником данных.

Внутри компонента store читается через префикс `$`: запись `$theme` в шаблоне автоматически подписывается на store и отписывается при размонтировании. Это снимает ручное управление подпиской. Запись в `$theme` эквивалентна вызову set, что делает store удобным двусторонним каналом общего состояния.

readable принимает функцию старта, которая получает set и возвращает функцию очистки. Это идеальная обёртка для WebSocket или таймера: store сам подключается при первой подписке и отключается, когда подписчиков не осталось.

Зачем нужен store, если есть руна `$state`?

Когда руны, когда stores

Граница простая. Если состояние нужно одному компоненту и его потомкам через props - это `$state.` Если одно значение читают и меняют несколько несвязанных компонентов - это store. Руны оптимальны для локальной реактивности и производных, stores для пересечения границ компонентов и интеграции с внешними источниками.

СвойствоРуны ($state, $derived)Stores (writable, readable)
ОбластьЛокально в компонентеОбщая между компонентами
ПодпискаАвтоматически компиляторомЧерез $ в шаблоне или subscribe вне него
Доступ вне компонентаНет напрямуюЕсть через subscribe, set, update
Производные$derivedderived
Где уместноСостояние одного компонента и его поддереваТема, пользователь, тосты, внешние потоки

Руны и stores не конкурируют, а дополняют друг друга. В Svelte 5 их можно связывать: значение store читается в руну, а реактивное состояние оборачивается в store-подобный объект для общего доступа. Этот интероп - отдельная важная тема, которую подробно разбирает курс по Svelte вместе с паттернами SvelteKit.

Здесь дан обзор для сравнения с другими фреймворками: руны это локальная реактивность уровня сигналов, stores это наблюдаемые значения уровня общего состояния. Полный разбор API, интеропа и серверной загрузки данных идёт в курсе по Svelte.

Тема приложения (light/dark) переключается в настройках и влияет на шапку, контент и подвал - три несвязанных компонента. Что разумнее в Svelte?

Связь с другими темами

Этот урок даёт обзор. Полный разбор Svelte-инструментов идёт в профильном курсе:

  • Stores и интероп рун в Svelte — Реальный код writable и readable, интероп рун и stores, паттерны SvelteKit разобраны в курсе по Svelte
  • Observable и Proxy — Store Svelte это наблюдаемое значение с подпиской, прямое продолжение модели observable

Итог

  • Svelte 5 вводит руны: $state объявляет реактивное состояние, $derived строит производные значения
  • Руны покрывают локальное состояние компонента: компилятор отслеживает зависимости и обновляет DOM точечно
  • Stores (writable, readable) решают задачу общего состояния между несвязанными компонентами
  • Store это наблюдаемое значение с методами subscribe, set и update, доступное и вне компонентов
  • Префикс $ в шаблоне автоматически подписывается на store и отписывается при размонтировании
  • Руны для локального реактивного состояния, stores для общего, детали и интероп разбираются в курсе по Svelte

Связанные уроки

  • sm-08-observable-proxy — Stores Svelte это наблюдаемые значения с подпиской, прямое продолжение модели observable из прошлого урока
  • sv-32-stores-interop — Полный разбор stores, интеропа рун и stores и реальный код Svelte живут в курсе по Svelte
Svelte: руны и stores

0

1

Войти