Context API в Preact предоставляет механизм передачи данных через дерево компонентов без необходимости вручную передавать пропсы на каждом уровне. Этот инструмент особенно полезен для глобального состояния приложения, темы, локализации и любых других данных, которые должны быть доступны множеству компонентов на разных уровнях вложенности.
Контекст создаётся с помощью функции createContext. Она
возвращает объект с двумя ключевыми свойствами: Provider и
Consumer.
import { createContext } from 'preact';
const ThemeContext = createContext('light');
Параметр 'light' — это значение по умолчанию, которое
будет использоваться, если компонент не находится внутри
Provider.
Provider используется для определения значения
контекста, которое будет доступно всем дочерним компонентам.
import { h } from 'preact';
import { ThemeContext } from './ThemeContext';
const App = () => (
<ThemeContext.Provider value="dark">
<Header />
<Content />
</ThemeContext.Provider>
);
Здесь все компоненты внутри Provider смогут получить
значение 'dark'. Provider может быть
вложенным, и внутренний Provider перекрывает значение
внешнего.
Consumer позволяет подписаться на контекст и
использовать его значение внутри компонента.
import { h } from 'preact';
import { ThemeContext } from './ThemeContext';
const Header = () => (
<ThemeContext.Consumer>
{theme => <h1 className={theme}>Заголовок</h1>}
</ThemeContext.Consumer>
);
Функция внутри Consumer получает текущее значение
контекста и возвращает JSX.
useContextВ Preact X и выше рекомендуется использовать хук
useContext, который упрощает доступ к контексту:
import { h } from 'preact';
import { useContext } from 'preact/hooks';
import { ThemeContext } from './ThemeContext';
const Header = () => {
const theme = useContext(ThemeContext);
return <h1 className={theme}>Заголовок</h1>;
};
useContext делает компонент более компактным и читаемым
по сравнению с использованием Consumer.
Значение контекста может быть динамическим и обновляться с помощью состояния:
import { h } from 'preact';
import { useState } from 'preact/hooks';
import { ThemeContext } from './ThemeContext';
const App = () => {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme(prev => (prev === 'light' ? 'dark' : 'light'));
};
return (
<ThemeContext.Provider value={theme}>
<button onCl ick={toggleTheme}>Переключить тему</button>
<Header />
</ThemeContext.Provider>
);
};
Все компоненты, использующие контекст через useContext
или Consumer, автоматически перерисуются при изменении
значения.
Использование контекста облегчает передачу данных, но может повлиять на производительность при частых изменениях:
Контекст может хранить сложные объекты и функции, что позволяет использовать его для глобального состояния и управления действиями:
const AuthContext = createContext({
user: null,
login: () => {},
logout: () => {}
});
const App = () => {
const [user, setUser] = useState(null);
const login = name => setUser({ name });
const logout = () => setUser(null);
return (
<AuthContext.Provider value={{ user, login, logout }}>
<Profile />
</AuthContext.Provider>
);
};
Компоненты внутри AuthContext могут вызывать
login и logout напрямую, а также получать
текущее состояние пользователя.
Context API в Preact — мощный инструмент для организации глобальных
данных и их передачи через компоненты без необходимости пробрасывать
пропсы на каждом уровне. Правильное использование Provider,
Consumer и useContext позволяет создавать
чистую и легко поддерживаемую архитектуру приложения.