Stores: writable, readable, derived

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

Writable Store

Writable store — это основной тип хранилища в Svelte. Он предоставляет механизм для хранения данных и позволяет их изменять. Компоненты, подписанные на данный store, будут автоматически обновляться при изменении состояния. Writable store реализуется через функцию writable, которая принимает начальное значение и возвращает объект с двумя ключевыми методами: set и update.

Пример использования writable store
import { writable } from 'svelte/store';

const counter = writable(0);

// Установка нового значения
counter.set(10);

// Обновление значения с помощью функции
counter.update(n => n + 1);

В примере выше создается store counter, который хранит число. С помощью метода set можно установить его значение в 10, а метод update позволяет инкрементировать значение.

Особенности writable store:
  • Объект, возвращаемый функцией writable, является реактивным. Это означает, что все компоненты, подписанные на него, будут автоматически обновляться при изменении состояния.
  • Метод set используется для явной установки значения, а метод update — для изменения текущего состояния на основе его предыдущего значения.

Readable Store

Readable store — это хранилище, которое только предоставляет данные для чтения. Оно не позволяет изменять свои значения напрямую, и обычно используется для хранения состояний, которые вычисляются на основе других данных или предоставляются из внешних источников.

Readable store создается с помощью функции readable, которая принимает начальное значение и функцию для получения данных.

Пример использования readable store
import { readable } from 'svelte/store';

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

  return () => clearInterval(interval);
});

Здесь time — это readable store, который хранит текущее время. Каждый раз, когда происходит обновление времени, компонент, подписанный на этот store, будет перерисован. Важно, что в readable нельзя изменять данные напрямую, они обновляются автоматически в соответствии с функцией, переданной в readable.

Особенности readable store:
  • Хранилище доступно только для чтения.
  • Для его обновления используется функция, которая передается при создании store. Эта функция имеет доступ к методу set для обновления значения.
  • Используется, например, для получения данных, которые обновляются извне, или для вычисления значений на основе других данных.

Derived Store

Derived store — это особый тип хранилища, который позволяет создавать новые stores, основываясь на значениях других stores. Это полезно, когда требуется вычислить или преобразовать данные на основе уже существующего состояния. Для создания derived store используется функция derived.

Пример использования derived store
import { writable, derived } from 'svelte/store';

const count = writable(0);

const doubleCount = derived(count, $count => $count * 2);

В этом примере doubleCount является derived store, который будет хранить значение, в два раза большее, чем текущее значение из count. При каждом обновлении count значение doubleCount будет автоматически пересчитываться.

Особенности derived store:
  • Позволяет создавать новые stores на основе других stores.
  • Все изменения в исходных данных автоматически отражаются в производных значениях.
  • При необходимости можно использовать функцию для вычисления значения, основываясь на нескольких исходных данных.

Работа с несколькими Stores

Один из мощных аспектов Svelte — это возможность комбинировать различные типы stores. Например, можно использовать несколько writable stores и создать derived store, который будет зависеть от их значений.

Пример комбинирования writable и derived store
import { writable, derived } from 'svelte/store';

const firstName = writable('John');
const lastName = writable('Doe');

const fullName = derived(
  [firstName, lastName],
  ([$firstName, $lastName]) => `${$firstName} ${$lastName}`
);

Здесь fullName — это derived store, который зависит от двух writable stores (firstName и lastName). При изменении любого из этих stores значение fullName будет пересчитано автоматически.

Подписка и реактивность

С момента подписки на store компоненты автоматически обновляются при изменении данных в store. Подписка осуществляется через $-синтаксис в компоненте:

<script>
  import { writable } from 'svelte/store';

  const count = writable(0);
</script>

<button on:click={() => $count += 1}>
  Count: {$count}
</button>

В данном примере компонент будет автоматически обновляться, когда значение store count изменится. Этот механизм является основой реактивности в Svelte.

Преимущества использования stores

  1. Централизованное хранилище состояния: Stores позволяют централизованно управлять состоянием, доступным для нескольких компонентов, что упрощает передачу данных и управление состоянием в крупных приложениях.

  2. Реактивность: Благодаря реактивности компоненты автоматически обновляются при изменении состояния. Это избавляет от необходимости вручную отслеживать и обновлять DOM.

  3. Простота синхронизации: С помощью derived stores можно легко синхронизировать изменения состояния между различными компонентами, создавая производные данные на основе уже существующих.

  4. Производительность: Svelte эффективно обрабатывает изменения в состоянии, минимизируя перерасчет и обновление компонентов, что помогает достигать высокой производительности.

Заключение

Svelte предоставляет мощный механизм управления состоянием через различные типы stores: writable, readable и derived. Эти stores позволяют легко работать с состоянием, передавать данные между компонентами и автоматически обновлять UI. Они обеспечивают высокую реактивность и производительность, делая приложение более предсказуемым и управляемым.