useContext для глобального состояния

Хук useContext позволяет передавать данные через дерево компонентов без явной передачи пропсов на каждом уровне. Это особенно полезно в мобильных приложениях, где одни и те же данные (например, тема интерфейса или статус авторизации) нужны во многих экранах.

Создание контекста

Контекст создаётся с помощью функции createContext. Ей можно передать значение по умолчанию — оно будет использовано, если компонент окажется вне провайдера:

import { createContext } from 'react';

type Theme = {
  darkMode: boolean;
};

const ThemeContext = createContext<Theme>({ darkMode: false });

Обёртка провайдером

Чтобы сделать данные доступными для дочерних компонентов, нужно обернуть часть дерева компонентов в <ThemeContext.Provider>. Значение передаётся через пропс value:

import { useState } from 'react';

export default function App() {
  const [darkMode, setDarkMode] = useState(false);

  return (
    <ThemeContext.Provider value={{ darkMode }}>
      {/* Весь ваш навигатор или корневой экран */}
      <MainScreen />
    </ThemeContext.Provider>
  );
}

Использование в компонентах

В любом вложенном компоненте можно получить доступ к данным контекста с помощью хука useContext:

import { useContext } from 'react';
import { View, Text } from 'react-native';

function SettingsScreen() {
  const { darkMode } = useContext(ThemeContext);

  return (
    <View style={{ backgroundColor: darkMode ? '#000' : '#fff' }}>
      <Text style={{ color: darkMode ? '#fff' : '#000' }}>
        Темный режим: {darkMode ? 'включён' : 'выключен'}
      </Text>
    </View>
  );
}

Когда использовать useContext

Этот подход подходит для:

  • переключения темы приложения,
  • хранения языка интерфейса,
  • отслеживания состояния авторизации (например, isAuthenticated),
  • передачи конфигурации API или настроек пользователя.

Однако не стоит злоупотреблять контекстом. Если данные нужны только в одном или двух компонентах, лучше передавать их через пропсы. Контекст наиболее эффективен, когда одни и те же данные используются на разных уровнях вложенности.

Важное замечание

Контекст не предназначен для высокочастотных обновлений (например, анимаций или быстрого ввода текста). При каждом изменении значения в провайдере все компоненты, подписанные на этот контекст, будут перерисовываться. Поэтому рекомендуется передавать через контекст только стабильные данные или разбивать контексты на мелкие (например, отдельно для темы, отдельно для авторизации).