← Назад к вопросам

В чем разница между React Context и useContext?

2.0 Middle🔥 171 комментариев
#React

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В чем разница между React Context и useContext

Основное уточнение

Eslo это не совсем правильная пара для сравнения. React Context — это API, а useContext — это хук для использования Context. Это как сравнивать "что такое электричество" и "как включить лампу". Но вопрос часто подразумевает путаницу, поэтому разберём всё подробно.

React Context API

Создание Context

import { createContext } from 'react';

// React.Context создаётся один раз
const ThemeContext = createContext();

// Это просто объект с методами Provider и Consumer
console.log(ThemeContext);
// {
//   $$typeof: Symbol(react.context)
//   Provider: {...}
//   Consumer: {...}
// }

Context — это объект, содержащий информацию о том, как передавать данные вниз по дереву компонентов.

Provider и Consumer

// Provider - оборачивает компоненты
<ThemeContext.Provider value={{ dark: true }}>
  <Header />
  <Main />
  <Footer />
</ThemeContext.Provider>

// Consumer - класс-компонент способ доступа (старый)
<ThemeContext.Consumer>
  {value => <div>{value.dark ? 'Dark' : 'Light'}</div>}
</ThemeContext.Consumer>

useContext Hook

Что это такое

// useContext - это хук для доступа к значению Context
const theme = useContext(ThemeContext);

// Это "синтаксический сахар" вместо Consumer
// Вместо:
<ThemeContext.Consumer>
  {value => /* используй value */}
</ThemeContext.Consumer>

// Пишешь:
const value = useContext(ThemeContext);
// Используй value

useContext — это хук, который позволяет получить значение из Context внутри компонента.

Детальное сравнение

До useContext (класс-компоненты)

// Context создаётся один раз
const AuthContext = createContext(null);

// Provider
function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  
  return (
    <AuthContext.Provider value={{ user, setUser }}>
      {children}
    </AuthContext.Provider>
  );
}

// Consumer (класс-компонент)
class UserProfile extends React.Component {
  static contextType = AuthContext;  // Единственный Context может быть
  
  render() {
    const { user } = this.context;
    return <div>{user?.name}</div>;
  }
}

// Или функциональный компонент с Consumer
function UserCard() {
  return (
    <AuthContext.Consumer>
      {({ user }) => <div>{user?.name}</div>}
    </AuthContext.Consumer>
  );
}

С useContext (современный подход)

// Context создаётся один раз (такой же)
const AuthContext = createContext(null);

// Provider (такой же)
function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  
  return (
    <AuthContext.Provider value={{ user, setUser }}>
      {children}
    </AuthContext.Provider>
  );
}

// Компонент с useContext (намного проще!)
function UserProfile() {
  const { user } = useContext(AuthContext);
  return <div>{user?.name}</div>;
}

function UserCard() {
  const { user } = useContext(AuthContext);
  return <div>{user?.name}</div>;
}

Практический пример: Theme Context

// 1. Создание Context (один раз)
const ThemeContext = createContext();

// 2. Provider компонент
function ThemeProvider({ children }) {
  const [isDark, setIsDark] = useState(false);
  
  const toggleTheme = () => {
    setIsDark(prev => !prev);
  };
  
  return (
    <ThemeContext.Provider value={{ isDark, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

// 3. Кастомный хук для удобства
function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme должен быть внутри ThemeProvider');
  }
  return context;
}

// 4. Использование в компонентах
function Header() {
  const { isDark, toggleTheme } = useTheme();
  
  return (
    <header style={{ background: isDark ? '#000' : '#fff' }}>
      <button onClick={toggleTheme}>
        {isDark ? 'Light' : 'Dark'}
      </button>
    </header>
  );
}

// 5. Обёртка приложения
function App() {
  return (
    <ThemeProvider>
      <Header />
      <Main />
      <Footer />
    </ThemeProvider>
  );
}

Сравнение в таблице

АспектReact ContextuseContext
ТипAPI, объектХук
Когда создаётсяОдин раз-
Где используетсяProvider/ConsumerВнутри функциональных компонентов
Синтаксис<Context.Provider>const value = useContext(Context)
СовместимостьВсё (классы и функции)Только функциональные компоненты
СложностьМногословноПросто
ПроизводительностьОдинаковаяОдинаковая

Важные моменты

1. Context сам по себе не вызывает перендер

const UserContext = createContext();

function App() {
  const [count, setCount] = useState(0);
  
  // При каждом рендере создаётся новый объект!
  // Это вызовет ненужные перендеры всех потребителей
  const value = { count, setCount };  // ПЛОХО!
  
  return (
    <UserContext.Provider value={value}>
      <Child />
    </UserContext.Provider>
  );
}

2. Оптимизация Context

function App() {
  const [count, setCount] = useState(0);
  
  // Мемоизируй значение
  const value = useMemo(() => ({ count, setCount }), [count]);
  
  return (
    <UserContext.Provider value={value}>
      <Child />
    </UserContext.Provider>
  );
}

3. Multiple Contexts

// useContext работает с одним Context
const theme = useContext(ThemeContext);
const auth = useContext(AuthContext);
const settings = useContext(SettingsContext);

// Несколько Provider'ов
function App() {
  return (
    <AuthProvider>
      <ThemeProvider>
        <SettingsProvider>
          <Main />
        </SettingsProvider>
      </ThemeProvider>
    </AuthProvider>
  );
}

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

Context хорош для:

  • Глобального состояния (тема, язык, профиль пользователя)
  • Избегания prop drilling
  • Конфигурации приложения

Context НЕ подходит для:

  • Часто меняющихся данных (вызывает лишние перендеры)
  • Сложного состояния (используй Redux, Zustand)
  • Больших объёмов данных

Заключение

React Context API — это механизм для передачи данных вниз по дереву компонентов. useContext — это хук, который позволяет получить значение из Context в функциональных компонентах.

Это не альтернативы друг другу, а части одного целого. Context API без useContext возможен (через Consumer), но useContext без Context невозможен — он всегда работает с Context объектом.

В чем разница между React Context и useContext? | PrepBro