Haunted — это современная библиотека для работы с веб-компонентами в стиле Web Components, построенная поверх нативного API браузера и использующая React-подобные хуки. Одной из ключевых концепций для организации состояния между компонентами является контекст. Контекст позволяет передавать данные глубоко во вложенные компоненты, не используя цепочки пропсов.
Для создания контекста используется функция
createContext. Она возвращает объект с двумя свойствами:
Provider и Consumer.
import { createContext } from 'haunted';
const ThemeContext = createContext('light'); // 'light' — значение по умолчанию
Ключевые моменты:
Provider.Provider оборачивает компоненты и передает им значение
через контекст. Его основной проп — value.
import { html, component } from 'haunted';
const App = () => html`
<${ThemeContext.Provider} .value=${'dark'}>
<theme-display></theme-display>
<//>
`;
customElements.define('app-root', component(App));
Особенности:
value вызывает реактивное обновление всех
потребляющих компонентов.Provider можно вкладывать друг в друга, создавая
локальные области действия контекста.Для получения значения контекста используется хук
useContext.
import { useContext } from 'haunted';
const ThemeDisplay = () => {
const theme = useContext(ThemeContext);
return html`Текущая тема: ${theme}`;
};
customElements.define('theme-display', component(ThemeDisplay));
Важные моменты:
useContext должен вызываться только внутри компонента,
созданного с помощью component.Provider автоматически
обновляет все компоненты, использующие useContext.Контекст в Haunted полностью интегрирован с системой реактивности
библиотеки. Если значение в Provider изменяется
динамически, все потребляющие компоненты обновляются без необходимости
вручную подписываться на события.
const ThemeSwitcher = () => {
const [theme, setTheme] = useState('light');
return html`
<${ThemeContext.Provider} .value=${theme}>
<theme-display></theme-display>
<button @click=${() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Переключить тему
</button>
<//>
`;
};
customElements.define('theme-switcher', component(ThemeSwitcher));
Особенности динамических изменений:
useState работает совместно с Provider для
реактивного обновления контекста.Haunted позволяет создавать несколько уровней контекста. Вложенные
Provider переопределяют значение только для своей
области:
const Outer = () => html`
<${ThemeContext.Provider} .value=${'blue'}>
<Inner></Inner>
<//>
`;
const Inner = () => html`
<${ThemeContext.Provider} .value=${'red'}>
<theme-display></theme-display>
<//>
`;
theme-display внутри
Inner получит значение 'red', а компоненты вне
Inner — 'blue'.Контекст удобно использовать для передачи не только данных, но и функций:
const CounterContext = createContext({ count: 0, increment: () => {} });
const CounterProvider = () => {
const [count, setCount] = useState(0);
const contextValue = {
count,
increment: () => setCount(count + 1),
};
return html`
<${CounterContext.Provider} .value=${contextValue}>
<counter-display></counter-display>
<//>
`;
};
const CounterDisplay = () => {
const { count, increment } = useContext(CounterContext);
return html`
<div>Счётчик: ${count}</div>
<button @click=${increment}>Увеличить</button>
`;
};
Выводы по объектам и функциям:
useState или
useReducer.Контексты в Haunted работают через Shadow DOM. Это значит, что контекст проходит через компоненты с Shadow DOM, не требуя каких-либо дополнительных механизмов:
customElements.define('shadow-wrapper', component(() => html`
<div>
<slot></slot>
</div>
`));
<shadow-wrapper> смогут
использовать useContext без проблем.Контекст в Haunted обеспечивает мощный и простой способ организации состояния между веб-компонентами. Он поддерживает динамические обновления, вложенные провайдеры, передачу объектов и функций, а также полностью интегрируется с реактивной моделью библиотеки. Это делает Haunted эффективным инструментом для построения сложных интерфейсов на базе Web Components.