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

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

2.0 Middle🔥 231 комментариев
#React#Архитектура и паттерны

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

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

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

Разница между Context и State в React

Context и State — это два способа управления данными в React, но они служат разным целям и имеют существенные различия в использовании, производительности и сценариях применения.

Основные различия

1. Назначение и область применения

State - локальное состояние компонента:

import { useState } from 'react';

function Counter() {
  // State принадлежит только этому компоненту
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

Context - глобальные данные для дерева компонентов:

import { createContext, useState } from 'react';

const CountContext = createContext();

function CountProvider({ children }) {
  const [count, setCount] = useState(0);
  
  return (
    <CountContext.Provider value={{ count, setCount }}>
      {children}
    </CountContext.Provider>
  );
}

// Используется на верхнем уровне
export default function App() {
  return (
    <CountProvider>
      <Header />
      <Main />
      <Footer />
    </CountProvider>
  );
}

2. Область видимости

State - только для компонента и его детей (через props):

function Parent() {
  const [message, setMessage] = useState('Hello');
  
  return <Child message={message} onChange={setMessage} />;
}

function Child({ message, onChange }) {
  // Доступно только через props
  return <input value={message} onChange={(e) => onChange(e.target.value)} />;
}

Context - для всего поддерева без prop drilling:

const MessageContext = createContext();

function Parent() {
  const [message, setMessage] = useState('Hello');
  
  return (
    <MessageContext.Provider value={{ message, setMessage }}>
      <Child />
    </MessageContext.Provider>
  );
}

function Child() {
  // Даже на 5 уровней глубже
  return <GrandChild />;
}

function GrandChild() {
  const { message, setMessage } = useContext(MessageContext);
  return <input value={message} onChange={(e) => setMessage(e.target.value)} />;
}

3. Производительность

State - быстро и оптимизировано:

function Form() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  
  // Только компоненты, использующие firstName, перерисуются
  return (
    <>
      <InputField value={firstName} onChange={setFirstName} />
      <InputField value={lastName} onChange={setLastName} />
    </>
  );
}

Context - вызывает перерисовку всех потребителей:

const UserContext = createContext();

function App() {
  const [user, setUser] = useState({ name: 'John', age: 30 });
  
  return (
    <UserContext.Provider value={user}>
      {/* ВСЕ компоненты, использующие UserContext, перерисуются */}
      {/* когда изменится user - даже если используют только name */}
      <Header />
      <Sidebar />
      <Main />
    </UserContext.Provider>
  );
}

Оптимизация Context - мемоизация:

function UserProvider({ children }) {
  const [user, setUser] = useState({ name: 'John', age: 30 });
  
  // Мемоизируем value, чтобы не пересоздавался при каждом render
  const value = useMemo(() => ({ user, setUser }), [user]);
  
  return (
    <UserContext.Provider value={value}>
      {children}
    </UserContext.Provider>
  );
}

4. Обновление данных

State - функции сеттеры:

function Timer() {
  const [seconds, setSeconds] = useState(0);
  
  // Можно использовать текущее значение
  const handleIncrement = () => {
    setSeconds(prev => prev + 1);
  };
  
  return (
    <>
      <p>{seconds}</p>
      <button onClick={handleIncrement}>+</button>
    </>
  );
}

Context - обновление через функцию из Provider:

const TimerContext = createContext();

function TimerProvider({ children }) {
  const [seconds, setSeconds] = useState(0);
  
  const increment = () => setSeconds(prev => prev + 1);
  const reset = () => setSeconds(0);
  
  return (
    <TimerContext.Provider value={{ seconds, increment, reset }}>
      {children}
    </TimerContext.Provider>
  );
}

function Timer() {
  const { seconds, increment } = useContext(TimerContext);
  
  return (
    <>
      <p>{seconds}</p>
      <button onClick={increment}>+</button>
    </>
  );
}

5. Сложность управления

State - простой для одного компонента:

function UserProfile() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [loading, setLoading] = useState(false);
  
  // Легко управлять локальным состоянием
  const handleSubmit = async () => {
    setLoading(true);
    // ...
    setLoading(false);
  };
}

Context - полезен для сложных, глобальных данных:

const AppContext = createContext();

function AppProvider({ children }) {
  const [user, setUser] = useState(null);
  const [theme, setTheme] = useState('light');
  const [notifications, setNotifications] = useState([]);
  const [settings, setSettings] = useState({});
  
  // Вся глобальная логика в одном месте
  const value = {
    user, setUser,
    theme, setTheme,
    notifications, setNotifications,
    settings, setSettings
  };
  
  return (
    <AppContext.Provider value={value}>
      {children}
    </AppContext.Provider>
  );
}

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

  1. Локальное состояние компонента - форма, счетчик, видимость модального окна
  2. Данные, используемые только в этом компоненте
  3. Частые обновления - для лучшей производительности
  4. Простые структуры данных

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

  1. Глобальное состояние - авторизация, тема, язык
  2. Избегаю prop drilling - когда данные нужны на глубоко вложенных компонентах
  3. Редкие обновления - данные меняются не часто
  4. Данные, нужные многим компонентам

Комбинированный подход

// На уровне приложения - Context для глобального состояния
function App() {
  return (
    <AuthProvider>
      <ThemeProvider>
        <NotificationProvider>
          <MainApp />
        </NotificationProvider>
      </ThemeProvider>
    </AuthProvider>
  );
}

// На уровне компонента - State для локального состояния
function UserForm() {
  const { user, updateUser } = useContext(UserContext); // Global Context
  const [formData, setFormData] = useState(user); // Local State
  const [errors, setErrors] = useState({}); // Local State
  
  const handleSubmit = () => {
    updateUser(formData);
  };
  
  return (
    // Form JSX
  );
}

Альтернативы

Для более сложного управления состоянием я использую:

  • useReducer - для сложной логики обновления
  • Redux или Zustand - для очень больших приложений
  • React Query - для состояния с сервера

В итоге: State для локального, Context для глобального — это основной принцип, который я следую в разработке React приложений.

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