В SvelteKit derived stores представляют собой реактивные производные состояния, которые автоматически вычисляются на основе одного или нескольких других stores. Они позволяют создавать логически связанные данные, не дублируя состояние, и обеспечивают реактивность, характерную для Svelte.
import { writable, derived } from 'svelte/store';
const count = writable(0);
const doubled = derived(count, $count => $count * 2);
В этом примере doubled автоматически обновляется при
изменении значения count. При обращении к
$doubled получаем актуальное значение, без необходимости
вручную подписываться на изменения count.
const storeA = writable(10);
const storeB = derived(storeA, $storeA => $storeA + 5);
storeA — исходный store, от которого зависит derived
store.$storeA — значение исходного store внутри функции.storeB.Derived store может зависеть сразу от нескольких stores:
const firstName = writable('Иван');
const lastName = writable('Иванов');
const fullName = derived(
[firstName, lastName],
([$firstName, $lastName]) => `${$firstName} ${$lastName}`
);
Derived store поддерживает асинхронные операции. Например, можно выполнять запросы к API и хранить результат как derived store:
const userId = writable(1);
const userData = derived(userId, ($userId, set) => {
set(null); // начальное значение
fetch(`https://jsonplaceholder.typicode.com/users/${$userId}`)
.then(res => res.json())
.then(data => set(data));
});
set для
обновления значения асинхронно.const timer = derived(count, ($count, set) => {
const interval = setInterval(() => set($count + 1), 1000);
return () => clearInterval(interval);
});
Derived store вычисляет значение только при первой подписке. До подписки вычисления не выполняются, что экономит ресурсы:
const expensiveCalculation = derived(storeA, $storeA => {
console.log('Вычисление запущено');
return $storeA * 1000;
});
Сообщение Вычисление запущено появится только при первом
обращении через $expensiveCalculation или подписке
expensiveCalculation.subscribe(...).
const items = writable([1, 2, 3]);
const itemCount = derived(items, $items => $items.length);
const a = writable(2);
const b = writable(3);
const sum = derived([a, b], ([$a, $b]) => $a + $b);
const isModalOpen = writable(false);
const modalClass = derived(isModalOpen, $isModalOpen =>
$isModalOpen ? 'modal-open' : 'modal-closed'
);
const query = writable('svelte');
const searchResults = derived(query, ($query, set) => {
set([]);
const controller = new AbortController();
fetch(`https://api.example.com/search?q=${$query}`, { signal: controller.signal })
.then(res => res.json())
.then(data => set(data))
.catch(err => {
if (err.name !== 'AbortError') console.error(err);
});
return () => controller.abort();
});
Derived store можно использовать так же, как обычный writable store:
fullName.subscribe(value => console.log(value));
При этом каждый раз, когда изменяется хотя бы один исходный store, подписчики derived store получают новое значение.
Важно: derived store является чистым вычислением — он не хранит состояния самостоятельно, а всегда формирует его из зависимостей. Это обеспечивает согласованность данных и упрощает архитектуру приложения.
abort или clearInterval) при смене
зависимостей.writable,
readable).derived.$store или
store.subscribe.Derived stores позволяют строить сложные реактивные цепочки без лишнего кода и дублирования состояния, обеспечивая чистую архитектуру и гибкость при работе с UI в SvelteKit.