Контекст: setContext и getContext
Контекст — способ передать значение от компонента всем его потомкам, на любую глубину, не протаскивая его через свойства каждого промежуточного компонента. В отличие от модуля .svelte.js, контекст принадлежит конкретному дереву компонентов, поэтому безопасен при серверной отрисовке.
Положить значение
Родитель кладёт значение функцией setContext(ключ, значение) из модуля svelte:
<!-- src/routes/+page.svelte -->
<script>
import { setContext } from 'svelte';
import TodoCounter from '$lib/components/TodoCounter.svelte';
const todoStore = $state({
items: [
{ id: 1, text: 'Купить хлеб', done: false },
{ id: 2, text: 'Позвонить Олегу', done: true }
]
});
setContext('todos', todoStore);
</script>
<h1>Мои задачи <TodoCounter /></h1>Ключ — любая строка или символ. Значение — объект $state, чтобы потомки видели его изменения.
Получить значение
Любой вложенный компонент достаёт значение функцией getContext с тем же ключом:
<!-- src/lib/components/TodoCounter.svelte -->
<script>
import { getContext } from 'svelte';
const todoStore = getContext('todos');
let remaining = $derived(todoStore.items.filter((t) => !t.done).length);
</script>
<span>Осталось: {remaining}</span>В заголовке появится «Осталось: 1». TodoCounter не получает свойств: данные пришли через контекст.
Когда вызывать
setContext и getContext вызывают только при создании компонента — в начале блока <script>. В обработчике клика или в $effect они выдадут ошибку. Если значение нужно в обработчике, получите его заранее в переменную, как todoStore выше.
Удобные функции
Чтобы не повторять строковый ключ в разных файлах, обычно делают маленький модуль:
// src/lib/todo-context.js
import { getContext, setContext } from 'svelte';
const KEY = Symbol('todos');
export function setTodoContext(store) {
setContext(KEY, store);
}
export function getTodoContext() {
return getContext(KEY);
}Теперь в +page.svelte пишут setTodoContext(todoStore), а в потомках — const todoStore = getTodoContext(). Опечатка в ключе больше невозможна.
Контекст или модуль .svelte.js
Модуль .svelte.js | Контекст | |
|---|---|---|
| Видимость | вся программа | потомки одного компонента |
| На сервере | общий для всех посетителей | свой для каждого запроса |
| Где удобен | состояние только в браузере | данные пользователя, темы, настройки дерева |
Частая ошибка
Передать в контекст обычное значение и ждать обновлений:
<script>
import { setContext } from 'svelte';
let count = $state(0);
setContext('count', count);
</script>В контекст попадёт число 0 на момент вызова, и потомки не увидят дальнейших изменений. Передавайте объект $state (или функцию, возвращающую значение) и меняйте его свойства.