Skip to main content

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(...);