Writable и readable stores

В SvelteKit концепция stores предоставляет удобный способ управления состоянием приложения. Stores позволяют хранить данные вне компонентов, обеспечивая реактивное обновление интерфейса при изменении этих данных. Среди основных типов stores выделяются writable и readable, различающиеся возможностями записи и подписки.


Writable Stores

Writable store представляет собой двусторонне управляемое хранилище данных. Оно позволяет не только подписываться на изменения состояния, но и изменять его напрямую. Создание writable store происходит с помощью функции writable из пакета svelte/store:

import { writable } from 'svelte/store';

export const counter = writable(0);
  • counter — это store, начальное значение которого равно 0.
  • Любой компонент, подписанный на counter, будет автоматически реагировать на его изменения.

Методы writable store

  1. set(value) – устанавливает новое значение store и уведомляет всех подписчиков:
counter.set(5); // значение counter становится 5
  1. upd ate(callback) – принимает функцию, в которой можно изменить текущее значение store:
counter.update(n => n + 1); // увеличивает counter на 1
  1. subscribe(callback) – подписка на изменения store. Callback получает текущее значение:
const unsubscribe = counter.subscribe(value => {
    console.log('Текущее значение:', value);
});

// отмена подписки
unsubscribe();

Применение writable store

Writable stores удобно использовать для счётчиков, форм, тем оформления, состояния модальных окон. Они подходят там, где данные должны меняться из разных частей приложения.

Пример реактивного компонента с writable store:

<script>
    import { counter } from './stores.js';

    function increment() {
        counter.update(n => n + 1);
    }
</script>

<button on:click={increment}>
    Увеличить: {$counter}
</button>

Здесь $counter — это синтаксический сахар Svelte для автоматической подписки на store и получения текущего значения.


Readable Stores

Readable store используется для данных, которые не должны изменяться напрямую компонентом. Чаще всего это вычисляемые или асинхронные значения, которые обновляются извне (например, таймеры, события от веб-сокетов или API).

Создание readable store:

import { readable } from 'svelte/store';

export const time = readable(new Date(), se t => {
    const interval = setInterval(() => {
        set(new Date());
    }, 1000);

    return () => clearInterval(interval); // функция очистки при отписке
});
  • set — функция, вызываемая для обновления значения store.
  • Возвращаемая функция используется для очистки ресурсов при отписке, например, остановки интервала или закрытия сокета.

Особенности readable store

  • Readable store не предоставляет методов set и update напрямую, доступно только чтение и подписка.
  • Используется для одностороннего потока данных, где компонент получает значения, но не изменяет их.

Пример использования в компоненте:

<script>
    import { time } from './stores.js';
</script>

<p>Текущее время: {$time.toLocaleTimeString()}</p>

Производные stores

Оба типа store могут быть использованы для создания derived stores, которые вычисляются на основе других store. Это полезно для комбинации нескольких источников данных или вычисления зависимых состояний.

import { derived } from 'svelte/store';
import { counter } from './stores.js';

export const doubleCounter = derived(counter, $counter => $counter * 2);
  • doubleCounter автоматически пересчитывается при изменении counter.
  • Подписка на derived store работает так же, как на writable или readable store.

Сравнение writable и readable

Характеристика writable readable
Изменяемость Да, через set и update Нет, только внешнее обновление
Подписка Да Да
Применение Данные, изменяемые компонентами Данные, изменяемые извне
Создание writable(initialValue) readable(initialValue, callback)

Writable store подходит для интерактивных элементов интерфейса, readable — для данных из внешних источников или вычисляемых состояний.


Практические советы

  • Всегда использовать $store для реактивного доступа к значениям внутри компонентов.
  • Readable store следует применять для асинхронных данных и подписок на события, чтобы избежать прямого вмешательства компонента в поток данных.
  • Writable store хорошо комбинировать с derived для вычисления зависимых значений без дублирования логики.

Использование writable и readable stores в SvelteKit обеспечивает мощную реактивную архитектуру, позволяя управлять состоянием приложения чисто, модульно и предсказуемо.