useContext — это хук, который обеспечивает доступ к
контексту в функциональных компонентах. Контекст используется для
передачи данных между компонентами без необходимости пробрасывать их
через пропсы на каждом уровне иерархии.
Создание контекста происходит с помощью функции
createContext. Она возвращает объект с двумя ключевыми
свойствами: Provider и Consumer. В современных
проектах Consumer используется редко, поскольку
useContext позволяет работать с контекстом напрямую.
import { createContext } from 'preact';
import { useContext } from 'preact/hooks';
const ThemeContext = createContext('light');
В этом примере создается контекст для темы с значением по умолчанию
'light'.
Provider используется для передачи значения контекста
дочерним компонентам. Он оборачивает часть дерева компонентов, где
контекст будет доступен.
<ThemeContext.Provider value="dark">
<App />
</ThemeContext.Provider>
Здесь все компоненты внутри <App /> смогут
получить доступ к значению "dark" через
useContext.
useContextХук useContext принимает объект контекста, созданный
через createContext, и возвращает текущее значение
контекста, которое было передано через Provider.
function Toolbar() {
const theme = useContext(ThemeContext);
return <div style={{ background: theme === 'dark' ? '#333' : '#fff' }}>Toolbar</div>;
}
Если Toolbar находится вне
<ThemeContext.Provider>, useContext
вернет значение по умолчанию 'light'.
Значение контекста можно обновлять динамически, передавая новое
значение в Provider. При этом все дочерние компоненты,
использующие useContext, автоматически перерисуются с новым
значением.
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={theme}>
<Toolbar />
<button onCl ick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Переключить тему
</button>
</ThemeContext.Provider>
);
}
В Preact допустимо использовать несколько контекстов одновременно.
Вложенные контексты не конфликтуют между собой, каждый компонент
получает значение именно того контекста, который был передан через
соответствующий Provider.
const AuthContext = createContext(null);
function UserProfile() {
const theme = useContext(ThemeContext);
const user = useContext(AuthContext);
return (
<div style={{ background: theme === 'dark' ? '#333' : '#fff' }}>
{user ? `Привет, ${user.name}` : 'Гость'}
</div>
);
}
В Preact useContext работает аналогично React, однако
Preact более легковесен, поэтому важно помнить о производительности при
частых обновлениях контекста. Каждый вызов setState в
Provider инициирует перерисовку всех компонентов,
использующих этот контекст. В крупных приложениях рекомендуется
разделять контексты для независимых данных, чтобы избежать лишних
ререндеров.
Provider.useContext с
useReducer для управления сложными состояниями внутри
контекста.const ThemeContext = createContext('light');
const AuthContext = createContext({ user: null });
function App() {
const [theme, setTheme] = useState('light');
const [user, setUser] = useState({ name: 'Алексей' });
return (
<ThemeContext.Provider value={theme}>
<AuthContext.Provider value={user}>
<Toolbar />
<button onCl ick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Переключить тему
</button>
</AuthContext.Provider>
</ThemeContext.Provider>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
const user = useContext(AuthContext);
return (
<div style={{ padding: '10px', background: theme === 'dark' ? '#333' : '#eee' }}>
{user ? `Пользователь: ${user.name}` : 'Гость'}
</div>
);
}
Этот пример демонстрирует совместное использование нескольких контекстов и динамическое обновление данных без передачи пропсов через все уровни компонентов. Контекст в Preact позволяет строить гибкую архитектуру состояния, делая код более читаемым и масштабируемым.