Haunted — это библиотека для создания реактивных веб-компонентов на основе стандартов Web Components с использованием хуков, вдохновленных React. Одной из ключевых особенностей является поддержка контекстов, позволяющая компонентам взаимодействовать без необходимости явно передавать пропсы через несколько уровней вложенности. Работа с множественными контекстами требует особого внимания к структуре и порядку объявления провайдеров и потребителей контекста.
Контекст в Haunted создаётся с помощью функции
createContext. Результат — объект с двумя основными
свойствами: Provider и Consumer.
import { createContext } from 'haunted';
const ThemeContext = createContext('light');
const UserContext = createContext({ name: 'Guest', role: 'visitor' });
light.Создавая несколько контекстов, важно различать их по смыслу и назначению, чтобы не возникало путаницы при их использовании.
Каждый контекст должен иметь свой <Provider>.
Провайдер передаёт значение вниз по дереву компонентов. При
множественных контекстах провайдеры можно вложить, и
каждый компонент сможет подписаться на нужный ему контекст.
html`
<${ThemeContext.Provider} value="dark">
<${UserContext.Provider} value=${{ name: 'Alice', role: 'admin' }}>
<app-content></app-content>
<//>
<//>
`
Для получения значений контекста используется хук
useContext. Если компонент зависит сразу от нескольких
контекстов, можно вызвать useContext несколько раз.
import { component, useContext, html } from 'haunted';
function AppContent() {
const theme = useContext(ThemeContext);
const user = useContext(UserContext);
return html`
<div class=${theme}>
<p>Пользователь: ${user.name}</p>
<p>Роль: ${user.role}</p>
</div>
`;
}
customElements.define('app-content', component(AppContent));
useContext повторно безопасен и
не влияет на производительность, если используется корректно.value в провайдере компонент автоматически
перерисовывается.Изменение значения контекста происходит через изменение
value в провайдере. Для динамических данных удобно
использовать реактивные состояния (useState) или
вычисляемые значения (useReducer,
useMemo).
import { useState, html, component, useContext } from 'haunted';
function ThemeSwitcher() {
const [theme, setTheme] = useState('light');
return html`
<${ThemeContext.Provider} .value=${theme}>
<button @click=${() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Переключить тему
</button>
<app-content></app-content>
<//>
`;
}
customElements.define('theme-switcher', component(ThemeSwitcher));
value.Provider управляет только своим состоянием.Haunted позволяет сочетать множественные контексты с другими хуками, создавая мощные реактивные структуры:
function Dashboard() {
const theme = useContext(ThemeContext);
const user = useContext(UserContext);
const [notifications, setNotifications] = useState([]);
return html`
<div class=${theme}>
<h2>Привет, ${user.name}</h2>
<ul>
${notifications.map(n => html`<li>${n}</li>`)}
</ul>
<button @click=${() => setNotifications([...notifications, 'Новое сообщение'])}>
Добавить уведомление
</button>
</div>
`;
}
Оптимальная практика работы с множественными контекстами:
<ThemeProvider value="dark">
<UserProvider value={...}>
<AppContent />
</UserProvider>
</ThemeProvider>
Haunted делает работу с множественными контекстами простой и предсказуемой, обеспечивая реактивность и строгую структурированность компонентов.