Контекст в Haunted

Haunted — это современная библиотека для создания веб-компонентов на основе Web Components с использованием реактивного подхода, схожего с функциональными компонентами в React. Одним из ключевых механизмов, обеспечивающих гибкость и масштабируемость приложений на Haunted, является контекст. Контекст позволяет передавать данные между компонентами без необходимости пробрасывать их через цепочку props, что упрощает управление состоянием на уровне вложенных компонентов.


Основные принципы работы с контекстом

Контекст в Haunted строится вокруг двух основных функций: createContext и useContext.

  1. Создание контекста Функция createContext используется для определения нового контекста. Она возвращает объект с двумя свойствами:

    • Provider — компонент, который передает значение контекста вниз по дереву компонентов.
    • Consumer — хук, который позволяет дочернему компоненту получать текущее значение контекста.
import { createContext, useContext, component, html } from 'haunted';

const ThemeContext = createContext('light'); // Значение по умолчанию

Особенности:

  • Контекст создается один раз и используется во всех компонентах, которые должны обмениваться данными.
  • Значение по умолчанию используется только тогда, когда компонент не находится внутри соответствующего Provider.

Использование Provider

Provider оборачивает часть дерева компонентов и предоставляет им значение контекста. Любой компонент внутри этого дерева сможет получить доступ к этому значению через useContext.

const App = component(() => {
  return html`
    <${ThemeContext.Provider} value="dark">
      <Toolbar></Toolbar>
    <//>
  `;
});

Ключевые моменты:

  • Свойство value определяет текущее значение, которое будет доступно всем потомкам.
  • Provider может быть вложенным, при этом дочерние компоненты будут использовать ближайший по дереву Provider.

Получение значения контекста через useContext

Хук useContext позволяет компоненту получать текущее значение контекста. Он вызывается внутри функционального компонента и возвращает актуальное значение.

const Toolbar = component(() => {
  const theme = useContext(ThemeContext);
  
  return html`<div class=${theme}>Панель инструментов</div>`;
});

Особенности поведения:

  • Если компонент не находится внутри Provider, будет использовано значение по умолчанию.
  • Любое изменение value у Provider автоматически вызывает повторный рендер всех зависимых компонентов.

Динамическое обновление контекста

Контекст в Haunted поддерживает реактивность. Значение контекста можно менять динамически, используя обычное состояние или вычисляемые значения.

import { useState } from 'haunted';

const App = component(() => {
  const [theme, setTheme] = useState('light');

  return html`
    <button @click=${() => setTheme(theme === 'light' ? 'dark' : 'light')}>
      Сменить тему
    </button>
    <${ThemeContext.Provider} value=${theme}>
      <Toolbar></Toolbar>
    <//>
  `;
});

Важно: все компоненты, использующие useContext(ThemeContext), автоматически обновятся при смене theme.


Множественные контексты

Haunted позволяет использовать несколько контекстов одновременно. Для этого создается несколько объектов контекста, а компоненты могут подписываться на любые из них.

const UserContext = createContext(null);
const ThemeContext = createContext('light');

const UserProfile = component(() => {
  const user = useContext(UserContext);
  const theme = useContext(ThemeContext);
  
  return html`<div class=${theme}>Привет, ${user.name}</div>`;
});

Рекомендации по использованию:

  • Контексты стоит создавать для данных, которые реально нужны на разных уровнях компонентов, например, тема, пользователь, настройки приложения.
  • Избегать чрезмерного дробления контекста на мелкие значения, так как это может усложнить структуру приложения.

Особенности работы контекста в Haunted

  • Локальная изоляция: каждый Provider создаёт свою область действия, и значения не перетекают за пределы этой области.
  • Реактивность: любое обновление значения у Provider триггерит повторный рендер всех зависимых компонентов.
  • Композиция: контексты могут комбинироваться через вложенные Provider, создавая сложные и гибкие структуры данных.

Практические примеры

  1. Тема интерфейса: контекст хранит текущую тему (light/dark) и используется во всех визуальных компонентах для изменения стиля.
  2. Аутентификация: контекст хранит состояние пользователя и позволяет компонентам проверять права доступа без проброса props.
  3. Настройки приложения: контекст содержит глобальные настройки, такие как язык, регион или конфигурацию UI, доступные на всех уровнях компонента.

Контекст в Haunted становится мощным инструментом управления состоянием, обеспечивая простую и реактивную передачу данных через дерево компонентов без необходимости ручного проброса props, что особенно важно в крупных и сложных приложениях.