useContext
— это хук (hook) в React, который позволяет подписаться на контекст (context) без использования компонента-потребителя (Consumer). Это упрощает доступ к глобальным данным в дереве компонентов.
const value = useContext(MyContext);
import { createContext } from 'react';
const ThemeContext = createContext('light'); // Значение по умолчанию
function App() {
const [theme, setTheme] = useState('dark');
return (
<ThemeContext.Provider value={theme}>
<Toolbar />
<button onClick={() => setTheme(prev => prev === 'dark' ? 'light' : 'dark')}>
Сменить тему
</button>
</ThemeContext.Provider>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{
background: theme === 'dark' ? '#333' : '#EEE',
color: theme === 'dark' ? '#FFF' : '#000'
}}>
Кнопка с темой {theme}
</button>
);
}
// Создаем контекст
const UserContext = createContext(null);
// Компонент-провайдер
function App() {
const [user, setUser] = useState({ name: 'Анна', role: 'admin' });
return (
<UserContext.Provider value={{ user, setUser }}>
<Navbar />
<Profile />
</UserContext.Provider>
);
}
// Компонент-потребитель
function Profile() {
const { user } = useContext(UserContext);
return <div>Привет, {user.name}!</div>;
}
function Header() {
const theme = useContext(ThemeContext);
const user = useContext(UserContext);
return (
<header style={{ background: theme === 'dark' ? '#222' : '#DDD' }}>
Добро пожаловать, {user.name}!
</header>
);
}
function App() {
const [user, setUser] = useState({ name: 'Анна' });
// Мемоизированное значение контекста
const userValue = useMemo(() => ({ user, setUser }), [user]);
return (
<UserContext.Provider value={userValue}>
<Content />
</UserContext.Provider>
);
}
Использование useContext без Provider:
Ненужное использование контекста:
Забывают мемоизировать значение:
// Плохо: новый объект при каждом рендере
<UserContext.Provider value={{ user, setUser }}>
// Хорошо: мемоизированное значение
const value = useMemo(() => ({ user, setUser }), [user]);
<UserContext.Provider value={value}>
function useUser() {
const context = useContext(UserContext);
if (!context) {
throw new Error('useUser must be used within a UserProvider');
}
return context;
}
// Использование
const { user } = useUser();
const UserDispatch = createContext(null);
function App() {
const [user, dispatch] = useReducer(userReducer, initialUser);
return (
<UserDispatch.Provider value={dispatch}>
<UserState.Provider value={user}>
<Content />
</UserState.Provider>
</UserDispatch.Provider>
);
}
// В компоненте
function UpdateButton() {
const dispatch = useContext(UserDispatch);
return (
<button onClick={() => dispatch({ type: 'UPDATE_NAME', name: 'Новое имя' })}>
Обновить
</button>
);
}
useContext
— это мощный инструмент для управления глобальным состоянием приложения, который устраняет необходимость в пропс-дриллинге (prop drilling). Он предоставляет простой и элегантный способ доступа к данным контекста в функциональных компонентах. При правильном использовании с мемоизацией значений и разделением контекстов, он становится эффективным решением для управления состоянием приложения. Однако важно не злоупотреблять им и использовать только для действительно глобальных данных, которые нужны многим компонентам в разных частях приложения.