Когда приложение становится больше, управление состоянием компонентов превращается в настоящий вызов. Передача данных через 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

Без регистрации и смс