Когда приложение становится больше, управление состоянием компонентов превращается в настоящий вызов. Передача данных через props между множеством вложенных компонентов начинает напоминать игру в телефон, где вы передаёте одно сообщение через десяток звеньев. Но React приходит на помощь с Context API — инструментом, который делает работу с глобальным состоянием удобной и простой.
Сегодня разберём, что такое Context API, когда его использовать, и создадим приложение с возможностью переключения между светлой и тёмной темами.
Что такое Context API?
Context API — это встроенный инструмент React для управления глобальным состоянием. Он позволяет передавать данные между компонентами без необходимости прокидывать их через props.
Когда использовать Context API?
Context API подходит для:
- Тем оформления (тёмная/светлая тема).
- Настроек пользователя (например, язык интерфейса).
- Авторизации (хранение информации о текущем пользователе).
- Любых данных, которые нужны многим компонентам.
Если данные нужны только одному или двум компонентам, проще обойтись props или локальным состоянием (useState).
Как работает Context API?
- Создание контекста: Это «контейнер», в котором хранятся ваши данные. Он создаётся с помощью React.createContext().
- Провайдер (Provider): Провайдер оборачивает дерево компонентов и предоставляет данные из контекста.
- Потребители (Consumers): Компоненты, которые получают доступ к данным из контекста.
Пример структуры
import React, { createContext, useState, useContext } from 'react';
// Создаём контекст
const MyContext = createContext();
// Провайдер
const MyProvider = ({ children }) => {
const [state, setState] = useState('Hello, Context!');
return (
<MyContext.Provider value={{ state, setState }}>
{children}
</MyContext.Provider>
);
};
// Потребитель
const MyConsumer = () => {
const { state, setState } = useContext(MyContext);
return (
<View>
<Text>{state}</Text>
<Button title="Изменить" onPress={() => setState('Новый текст!')} />
</View>
);
};
// Использование
const App = () => (
<MyProvider>
<MyConsumer />
</MyProvider>
);
Практика: приложение с темной и светлой темой
Теперь создадим приложение, где пользователь сможет переключаться между светлой и тёмной темами. Это отличный пример использования Context API, так как тема требуется многим компонентам.
Шаг 1: Создаём проект
Начните с создания нового проекта React Native (через Expo или CLI).
Шаг 2: Структура приложения
Создадим следующие файлы:
- ThemeContext.js — для управления темой.
- App.js — главный файл приложения.
- Несколько экранов, чтобы показать, как тема применяется.
ThemeContext.js
import React, { createContext, useState, useContext } from 'react';
// Создаём контекст для темы
const ThemeContext = createContext();
// Провайдер темы
export const ThemeProvider = ({ children }) => {
const [isDarkTheme, setIsDarkTheme] = useState(false); // Состояние темы
// Функция для переключения темы
const toggleTheme = () => {
setIsDarkTheme((prevTheme) => !prevTheme);
};
return (
<ThemeContext.Provider value={{ isDarkTheme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
// Хук для использования контекста темы
export const useTheme = () => useContext(ThemeContext);
App.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { ThemeProvider, useTheme } from './ThemeContext';
import { View, Text, Button, StyleSheet } from 'react-native';
const Stack = createStackNavigator();
// Главный экран
const HomeScreen = ({ navigation }) => {
const { isDarkTheme, toggleTheme } = useTheme();
return (
<View
style={[
styles.container,
{ backgroundColor: isDarkTheme ? '#333' : '#fff' },
]}
>
<Text style={[styles.text, { color: isDarkTheme ? '#fff' : '#000' }]}>
{isDarkTheme ? 'Тёмная тема' : 'Светлая тема'}
</Text>
<Button title="Переключить тему" onPress={toggleTheme} />
<Button title="Открыть другой экран" onPress={() => navigation.navigate('Details')} />
</View>
);
};
// Другой экран
const DetailsScreen = () => {
const { isDarkTheme } = useTheme();
return (
<View
style={[
styles.container,
{ backgroundColor: isDarkTheme ? '#333' : '#fff' },
]}
>
<Text style={[styles.text, { color: isDarkTheme ? '#fff' : '#000' }]}>
Это экран с {isDarkTheme ? 'тёмной' : 'светлой'} темой!
</Text>
</View>
);
};
// Главный компонент приложения
const App = () => {
return (
<ThemeProvider>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
</ThemeProvider>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
fontSize: 18,
},
});
export default App;
Что мы сделали?
- Создали контекст темы
- В ThemeContext.js создали провайдер (ThemeProvider), который хранит текущую тему и функцию для её переключения.
- Использовали провайдер в App.js
- Обернули всё приложение в ThemeProvider.
- Применили тему на экранах
- С помощью useTheme подключили данные из контекста и изменили стили в зависимости от текущей темы.
Дальнейшие улучшения
- Добавьте сохранение темы — используйте AsyncStorage, чтобы сохранять выбор пользователя между сессиями.
- Кастомизируйте NavigationContainer — React Navigation поддерживает тему через свой theme-пропс.
- Добавьте больше компонентов — примените тему к кнопкам, заголовкам, модальным окнам и т. д.
Комментарии
0