API контекста предоставляет механизм, позволяющий компонентам 'разговаривать' друг с другом, не передавая данные и функции через свойства, и не генерируя множество событий. Это одна из дополнительных возможностей, но она может быть полезной.
Пусть у нас есть приложение, которое показывает карту
Mapbox GL. Нам нужно нанести
на карту маркеры при помощи компонента <MapMarker>
. Но для этого нам придется
передавать ссылку на объект Mapbox через свойство в каждый экземпляр этого
компонента.
API контекста состоит из двух методов - setContext
и getContext
. Если
компонент вызывает setContext(key, context)
, то любой дочерний компонент
может получить нужный контекст с помощью const context = getContext(key)
.
Давайте сначала установим контекст. В Map.svelte
импортируйте setContext
из
svelte
и key
из mapbox.js
, затем вызовите setContext
:
import { onDestroy, setContext } from "svelte";
import { key, mapbox } from "./mapbox.js";
setContext(key, {
getMap: () => map,
});
Объект контекста может быть чем угодно. Как и в случае с
функциями жизненного цикла, setContext
и getContext
должны вызываться только во время инициализации компонента, а не после.
Например, вызов внутри функции onMount
, приведет к ошибке. В этом примере,
поскольку переменная map
не существует, пока компонент не будет смонтирован,
наш контекстный объект содержит функцию getMap
, а не саму map
.
Теперь на другом конце, в MapMarker.svelte
, мы можем получить ссылку на
экземпляр Mapbox:
import { getContext } from "svelte";
import { key, mapbox } from "./mapbox.js";
const { getMap } = getContext(key);
const map = getMap();
Маркеры теперь могут добавлять сами себя на карту.
Более законченная версия
<MapMarker>
также должна поддерживать удаление и изменение маркеров, но здесь мы просто демонстрируем работу с контекстом.
ключи контекста
В mapbox.js
вы можете найти такую строку:
const key = Symbol();
Технически мы можем использовать любое значение в качестве ключа — например, мы могли бы сделать setContext('mapbox', ...)
. Недостатком использования строки является то, что разные библиотеки компонентов могут случайно использовать одну и ту же; использование символов, с другой стороны, означает, что ключи гарантированно уникальны.
Контекст vs. хранилище
Контекст и хранилища кажутся похожими. Они отличаются тем, что хранилища доступны в любой части приложения, в то время как контекст доступен только для компонента и его потомков. Это может быть полезно, если вы хотите использовать несколько копий компонента, чтобы состояние одного не влияло на состояние других.
Впрочем, их можно использовать и совместно. Поскольку контекст не реактивен, значения, которые будут изменяться со временем, можно поместить в хранилища внутри контекста:
const { these, are, stores } = getContext(...);