---
title: Состояние, пропсы и контекст
questionDates:
  q-transfer-0449: '2026-10-01'
  q-transfer-0450: '2026-10-01'
seo:
  description: >-
    Тема «Состояние, пропсы и контекст» для собеседования React Developer. Что
    такое "состояние" (state) компонента в React? Как обновить состояние
    компонента?
  title: Состояние, пропсы и контекст — React Developer
---

[Все темы React Developer](/prep/react-developer)

Подтемы:

- [Состояние и пропсы](#q-14bee738d69b8182bee1ee953d941cf7)
- [Управление состоянием](#q-14bee738d69b8141a19bcb62066ead20)
- [Контекст и передача данных](#q-14bee738d69b8164a383e043874dd796)

## <strong>Что такое "состояние" (</strong><code>state</code><strong>) компонента в React?</strong> [#q-14bee738d69b8182bee1ee953d941cf7]

Состояние хранит данные компонента между рендерами. В классовом компоненте state является объектом; значение состояния, созданного useState, может иметь любой тип.

В классовом компоненте состояние задают в constructor или поле state и обновляют через setState. В функциональном используют useState или useReducer. Обновление ставится в очередь; новое значение доступно следующему рендеру.

Пример&#58;

```jsx
import React, { Component } from "react";

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0, // Начальное состояние
    };
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>Счетчик: {this.state.count}</p>
        <button onClick={this.increment}>Увеличить</button>
      </div>
    );
  }
}

export default Counter;
```

В этом примере компонент <code>Counter</code> имеет состояние <code>count</code>, которое обновляется при клике на кнопку. При вызове <code>setState&#40;&#41;</code>, React обновит состояние и перерендерит компонент, отображая новое значение <code>count</code>.

:::note[Ссылки для изучения]

1. [useState: состояние и обновление следующего рендера](https://reactdev.ru/reference/react/useState/)
1. [Классовое состояние и setState](https://reactdev.ru/reference/react/Component/)
1. [Состояние компонента и useState. Ulbi TV, с 19:42](https://www.youtube.com/watch?v=GNrdg3PzpJQ&t=1182s)

:::

---

## <strong>Как обновить состояние компонента?</strong> [#q-14bee738d69b81b998d9de59a807a2e4]

В классовом компоненте setState принимает объект обновлений или функцию от предыдущего состояния и поверхностно объединяет результат со state. В функциональном компоненте setter из useState принимает следующее значение или функцию от предыдущего значения и заменяет его целиком. Состояние нельзя изменять напрямую.

Пример использования <code>setState&#40;&#41;</code>&#58;

```jsx
import React, { Component } from "react";

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  increment = () => {
    // Обновление состояния с использованием объекта
    this.setState({ count: this.state.count + 1 });
  };

  decrement = () => {
    // Обновление состояния с использованием функции
    this.setState((prevState) => {
      return { count: prevState.count - 1 };
    });
  };

  render() {
    return (
      <div>
        <p>Счетчик: {this.state.count}</p>
        <button onClick={this.increment}>Увеличить</button>
        <button onClick={this.decrement}>Уменьшить</button>
      </div>
    );
  }
}

export default Counter;
```

В данном примере <code>increment&#40;&#41;</code> и <code>decrement&#40;&#41;</code> обновляют состояние <code>count</code> с помощью <code>setState&#40;&#41;</code>. Важно использовать функции при обновлении состояния, особенно если новое состояние зависит от предыдущего состояния, чтобы избежать проблем с асинхронностью.

:::note[Ссылки для изучения]

1. [useState: состояние и обновление следующего рендера](https://reactdev.ru/reference/react/useState/)
1. [Классовое состояние и setState](https://reactdev.ru/reference/react/Component/)
1. [Обновление состояния через setter useState. Ulbi TV, с 21:36](https://www.youtube.com/watch?v=GNrdg3PzpJQ&t=1296s)

:::

---

## <strong>Что такое пропсы (</strong><code>props</code><strong>) в React?</strong> [#q-14bee738d69b815ca900f7e3397dbb57]

"Пропсы" (<code>props</code>) в React - это механизм передачи данных от родительского компонента к дочернему. Они представляют собой атрибуты, которые задаются при создании компонента и не могут быть изменены самим компонентом, который их получает. Пропсы используются для передачи информации о состоянии или конфигурации компонента.

Пример использования пропсов&#58;

```jsx
import React from "react";

function Welcome(props) {
  return <h1>Привет, {props.name}!</h1>;
}

const App = () => {
  return <Welcome name="Алиса" />;
};

export default App;
```

В этом примере компонент <code>Welcome</code> принимает пропс <code>name</code> и использует его для вывода персонализированного приветствия. Компонент <code>App</code> передает значение "Алиса" в пропс <code>name</code> компонента <code>Welcome</code>.

Пропсы передаются в виде объекта и доступны как свойства (<code>props</code>) внутри дочернего компонента.

Использование пропсов позволяет создавать более гибкие и переиспользуемые компоненты, так как можно настраивать их поведение и отображение извне.

:::note[Ссылки для изучения]

1. [Передача props компоненту React](https://reactdev.ru/learn/passing-props-to-a-component/)
2. [Props как входные данные компонента. Ulbi TV, с 35:03](https://www.youtube.com/watch?v=GNrdg3PzpJQ&t=2103s)

:::

---

## <strong>В чем разница между состоянием и пропсами?</strong> [#q-14bee738d69b81308326c01298272a4d]

Состояние (<code>state</code>) и пропсы (<code>props</code>) - это два основных концепта в React, используемые для управления данными в компонентах. Они имеют разные цели и характеристики&#58;

<strong>Состояние (</strong>
<code>state</code>
<strong>)&#58;</strong>

1. Состояние - это внутренние данные компонента, которые могут изменяться во время выполнения.

1. Определяется и управляется самим компонентом, в котором оно находится.

1. Изменение состояния вызывает перерендеринг компонента, чтобы отобразить новое состояние.

1. Доступно только для компонента, в котором было определено состояние.

1. Обновляется через setState в классе, setter из useState или dispatch из useReducer в функциональном компоненте.

<strong>Пропсы (</strong>
<code>props</code>
<strong>)&#58;</strong>

1. Пропсы - это данные, передаваемые от родительского компонента к дочернему компоненту.

1. Нельзя изменить пропсы внутри дочернего компонента. Они считаются "только для чтения".

1. Пропсы служат для настройки и передачи данных в компоненты.

1. Используются для связи между различными компонентами и передачи информации вниз по иерархии.

1. При рендере родителя дочерний компонент обычно рендерится с новыми пропсами. memo может пропустить рендер, если пропсы не изменились.

Вкратце, состояние предназначено для хранения и управления изменяющимися данными внутри компонента, тогда как пропсы предназначены для передачи данных от родительского компонента к дочернему. Оба этих концепта помогают создавать динамичные и переиспользуемые интерфейсы в React приложениях.

:::note[Ссылки для изучения]

1. [useState: локальное изменяемое состояние](https://reactdev.ru/reference/react/useState/)
1. [Props: входные данные от родителя](https://reactdev.ru/learn/passing-props-to-a-component/)
   :::

---

## <strong>Как обновить состояние компонента после изменения</strong> <code>props</code><strong>?</strong> [#q-14bee738d69b817092aac51b5748f2d4]

В React существует несколько способов обновления состояния компонента после изменения его props. Это может потребоваться, когда компонент зависит от входящих props и должен реагировать на их изменения. Вот несколько подходов&#58;

1. <code>componentDidUpdate&#40;prevProps&#41;</code>
   <strong>&#58;</strong> Метод <code>componentDidUpdate&#40;&#41;</code>
    вызывается после обновления компонента. Вы можете сравнить предыдущие и
   текущие props с помощью параметра <code>prevProps</code> и 
   <code>this&#46;props</code>, и при необходимости обновить состояние&#58;

   ```javascript
   componentDidUpdate(prevProps) {
     if (this.props.someProp !== prevProps.someProp) {
       this.setState({ someState: newValue });
     }
   }
   ```

1. <code>getDerivedStateFromProps&#40;nextProps&#44; prevState&#41;</code>
   <strong>&#58;</strong> Этот статический метод вызывается перед рендерингом и
   каждый раз, когда происходит обновление props. Вы можете вернуть новое
   состояние на основе новых props&#58;

   ```javascript
   static getDerivedStateFromProps(nextProps, prevState) {
     if (nextProps.someProp !== prevState.prevPropValue) {
       return { someState: newValue };
     }
     return null;
   }
   ```

1. <code>useState</code> <strong>с</strong> <code>useEffect</code>
   <strong>&#58;</strong> Если вы используете функциональные компоненты, вы
   можете использовать <code>useState</code> для хранения состояния и 
   <code>useEffect</code> для реагирования на изменения props&#58;

   ```javascript
   import React, { useState, useEffect } from "react";

   function MyComponent(props) {
     const [state, setState] = useState(initialState);

     useEffect(() => {
       if (props.someProp !== state.someState) {
         setState({ someState: newValue });
       }
     }, [props.someProp]);

     //...
   }
   ```

Не копируйте props в state без необходимости&#58; вычисляйте производные значения во время рендера. Для полного сброса состояния можно изменить key компонента. getDerivedStateFromProps нужен лишь в редких случаях; Effect предназначен прежде всего для синхронизации с внешними системами. Примеры выше схематичны&#58; initialState и newValue должны быть определены, а отслеживаемое предыдущее значение пропса нужно обновлять вместе с состоянием.

:::note[Ссылки для изучения]

1. [Изменение props: сброс и корректировка состояния без лишнего эффекта](https://reactdev.ru/learn/you-might-not-need-an-effect/)
   :::

---

## <strong>Как передать данные между компонентами вверх и вниз по иерархии?</strong> [#q-14bee738d69b813b9f22f8fb028b93ea]

В React данные могут передаваться между компонентами вверх и вниз по иерархии с использованием пропсов (<code>props</code>) и колбэков (callback функций). Вот как это работает&#58;

<strong>
  Передача данных вниз по иерархии (от родителя к дочернему компоненту)&#58;
</strong>

1. <strong>Пропсы (props)&#58;</strong> Родительский компонент передает данные
   своему дочернему компоненту через пропсы. Дочерний компонент может получить
   доступ к этим данным как свойства (props).

Пример&#58;

```jsx
// Родительский компонент
import React from "react";
import ChildComponent from "./ChildComponent";

const ParentComponent = () => {
  const data = "Данные для дочернего компонента";

  return <ChildComponent dataProp={data} />;
};

// Дочерний компонент
import React from "react";

const ChildComponent = (props) => {
  return <p>{props.dataProp}</p>;
};

export default ChildComponent;
```

<strong>
  Передача данных вверх по иерархии (от дочернего компонента к родителю)&#58;
</strong>

1. <strong>Колбэки (callback функции)&#58;</strong> Родительский компонент
   передает функцию в качестве пропса дочернему компоненту. Дочерний компонент
   может вызвать эту функцию, передавая ей данные обратно вверх по иерархии.

Пример&#58;

```jsx
// Родительский компонент
import React, { useState } from "react";
import ChildComponent from "./ChildComponent";

const ParentComponent = () => {
  const [receivedData, setReceivedData] = useState("");

  const handleDataChange = (data) => {
    setReceivedData(data);
  };

  return (
    <div>
      <p>Полученные данные: {receivedData}</p>
      <ChildComponent onDataChange={handleDataChange} />
    </div>
  );
};

// Дочерний компонент
import React from "react";

const ChildComponent = (props) => {
  const sendDataToParent = () => {
    props.onDataChange("Данные от дочернего компонента");
  };

  return <button onClick={sendDataToParent}>Отправить данные</button>;
};

export default ChildComponent;
```

Это позволяет дочернему компоненту воздействовать на данные и состояние родительского компонента.

Используя этот подход, вы можете эффективно передавать и обновлять данные между компонентами вверх и вниз по иерархии.

:::note[Ссылки для изучения]

1. [Поднятие состояния и обмен через props и callbacks](https://reactdev.ru/learn/sharing-state-between-components/)
2. [Передача данных между компонентами. Ulbi TV, с 59:15](https://www.youtube.com/watch?v=GNrdg3PzpJQ&t=3555s)

:::

---

## <strong>Что такое "подъем состояния" (</strong><code>lifting state up</code><strong>)?</strong> [#q-14bee738d69b81d58757d41b7c3179d4]

"Подъем состояния" (<code>lifting state up</code>) - это паттерн в React, который предполагает перемещение состояния из дочерних компонентов в родительские компоненты, чтобы разделять и управлять состоянием на более высоком уровне и передавать его через пропсы.

Этот подход особенно полезен, когда несколько компонентов должны иметь доступ к одному и тому же состоянию или когда состояние должно быть синхронизировано между разными частями приложения.

Пример с подъемом состояния&#58;

```jsx
import React, { useState } from "react";

const TemperatureInput = ({ scale, temperature, onTemperatureChange }) => {
  return (
    <fieldset>
      <legend>Введите температуру в градусах {scale}:</legend>
      <input
        value={temperature}
        onChange={(e) => onTemperatureChange(e.target.value)}
      />
    </fieldset>
  );
};

const Calculator = () => {
  const [celsius, setCelsius] = useState("");
  const [fahrenheit, setFahrenheit] = useState("");

  const handleCelsiusChange = (value) => {
    setCelsius(value);
    setFahrenheit((value * 9) / 5 + 32);
  };

  const handleFahrenheitChange = (value) => {
    setFahrenheit(value);
    setCelsius(((value - 32) * 5) / 9);
  };

  return (
    <div>
      <TemperatureInput
        scale="C"
        temperature={celsius}
        onTemperatureChange={handleCelsiusChange}
      />
      <TemperatureInput
        scale="F"
        temperature={fahrenheit}
        onTemperatureChange={handleFahrenheitChange}
      />
    </div>
  );
};

export default Calculator;
```

В этом примере компонент <code>Calculator</code> поднимает состояние температур из <code>TemperatureInput</code> компонентов. При изменении температуры в одном из вводов, состояние поднимается в родительский компонент <code>Calculator</code>, который затем обновляет состояние для другого ввода, обеспечивая синхронизацию температур в обеих шкалах.

:::note[Ссылки для изучения]

1. [Поднятие состояния и обмен через props и callbacks](https://reactdev.ru/learn/sharing-state-between-components/)
2. [Передача данных между компонентами. Ulbi TV, с 59:15](https://www.youtube.com/watch?v=GNrdg3PzpJQ&t=3555s)

:::

---

## <strong>Что такое "нормализация состояния" (</strong><code>state normalization</code><strong>) в контексте управления состоянием приложения?</strong> [#q-14bee738d69b817daf8ad5e1a1dceb1d]

Нормализация состояния (<code>state normalization</code>) - это паттерн управления состоянием, который используется для организации данных в хранилище таким образом, чтобы обеспечить эффективное хранение, обновление и доступ к данным в Redux или других системах управления состоянием.

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

Пример&#58; Предположим, у нас есть список постов и список комментариев к этим постам. Вместо хранения комментариев внутри каждого поста (что может привести к дублированию данных), мы можем создать две коллекции&#58; "посты" и "комментарии", и использовать идентификаторы постов в комментариях для установления связи между ними.

Преимущества нормализации состояния&#58;

1. <strong>Экономия места&#58;</strong> Дублирование данных уменьшается, так как
   одни и те же данные не хранятся в нескольких местах.

1. <strong>Легкость обновления&#58;</strong> Изменение данных в одной коллекции
   автоматически отражается в других, где эти данные используются.

1. <strong>Быстрый доступ&#58;</strong> Поиск, фильтрация и доступ к данным
   ускоряются, так как данные разделены на более мелкие коллекции.

1. <strong>Прозрачность&#58;</strong> Структура хранилища становится более легко
   понимаемой и отслеживаемой.

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

:::note[Ссылки для изучения]

1. [Плоское состояние: объекты по ID вместо глубокой вложенности](https://reactdev.ru/learn/choosing-the-state-structure/)
   :::

---

## <strong>Как управлять состоянием между компонентами, не имеющими близкой связи?</strong> [#q-14bee738d69b8109b574e2d0b492506f]

Существует несколько методов для управления состоянием между компонентами, которые не имеют прямой связи. Вот некоторые из них&#58;

1. <strong>Поднятие состояния (</strong>
   <code>Lifting State Up</code>
   <strong>)&#58;</strong> Вы можете поднять состояние до ближайшего общего
   родительского компонента, который имеет доступ и к одному, и к другому
   компоненту. Затем передавайте это состояние как пропсы в каждый компонент.
   Этот подход особенно полезен, когда компоненты имеют общий родительский
   компонент, но не имеют прямой связи друг с другом.

1. <strong>Контекст (</strong>
   <code>Context API</code>
   <strong>)&#58;</strong> Используйте Context API, который позволяет передавать
   данные глубоко в дерево компонентов без явной передачи пропсов через все
   уровни. Создайте контекст и оберните ваше дерево компонентов этим контекстом.
   Таким образом, компоненты смогут получать доступ к данным из контекста, даже
   если они не находятся в прямой иерархии.

1. <strong>Глобальное состояние (</strong>
   <code>Global State</code>
   <strong>)&#58;</strong> Используйте библиотеки управления состоянием, такие
   как Redux или MobX, чтобы создать глобальное хранилище данных, доступное для
   всех компонентов. Это особенно полезно, если состояние нужно между
   компонентами, которые находятся далеко друг от друга в дереве компонентов.

1. <strong>Событийная система&#58;</strong> Реализуйте свою событийную систему,
   которая позволит компонентам подписываться на определенные события и
   передавать данные. Это можно сделать с помощью сторонних библиотек или
   самостоятельно.

1. <strong>RESTful API&#58;</strong> Если ваши компоненты общаются с сервером,
   вы можете использовать RESTful API для обмена данными между ними. Компоненты
   могут получать и отправлять данные через API.

1. <strong>Библиотеки для управления состоянием&#58;</strong> В зависимости от
   вашего опыта и требований, вы также можете рассмотреть использование
   библиотек управления состоянием, таких как Recoil, Zustand и других.

Выбор метода будет зависеть от конкретных требований вашего приложения, его архитектуры и сложности взаимодействия между компонентами.

:::note[Ссылки для изучения]

1. [Context: данные для компонентов глубоко в дереве](https://reactdev.ru/learn/passing-data-deeply-with-context/)
   :::

---

## <strong>Какие популярные библиотеки для управления состоянием вы знаете, помимо встроенного</strong> <code>useState</code><strong>?</strong> [#q-14bee738d69b8141a19bcb62066ead20]

Популярные библиотеки для управления состоянием в React&#58;

{/* prettier-ignore */}
1. <code>Redux</code>&#58;

    - Централизованное хранилище состояния с предсказуемым поведением.

    - Пример использования&#58;

        ```javascript
        import { createStore } from 'redux';
        import { Provider } from 'react-redux';
        ```

1. <code>MobX</code>&#58;

    - Реактивное управление состоянием с фокусом на наблюдаемых данных и реакциях.

    - Пример использования&#58;

        ```javascript
        import { observable } from 'mobx';
        import { observer } from 'mobx-react';
        ```

1. <code>Recoil</code>&#58;

    - Recoil использует атомы и селекторы, но его репозиторий архивирован в январе 2025 года. Это исторический пример, а не рекомендация для нового проекта.

    - Пример использования&#58;

        ```javascript
        import { RecoilRoot, atom, useRecoilState } from 'recoil';
        ```

1. <code>Zustand</code>&#58;

    - Легковесная и гибкая библиотека для управления состоянием.

    - Пример использования&#58;

        ```javascript
        import { create } from 'zustand';
        ```

1. <code>Context API</code>&#58;

    - Встроенный механизм для управления глобальным состоянием с помощью контекста.

    - Пример использования&#58;

        ```javascript
        import { createContext, useContext } from 'react';
        ```

Помимо встроенного <code>useState</code>, для управления состоянием в React популярны библиотеки Redux, MobX, Recoil, Zustand, а также встроенный Context API.

:::note[Ссылки для изучения]

1. [Zustand: хранилище состояния и подключение React-компонентов](https://reactdev.ru/libs/zustand/getting-started/introduction/)
   :::

---

## <strong>Какие паттерны использования</strong> <code>Redux</code> <strong>вы знаете?</strong> [#q-14bee738d69b81ad83b2ea21d27219b5]

Паттерны использования <code>Redux</code>&#58;

{/* prettier-ignore */}
1. <strong>Действия (</strong><code>Actions</code><strong>)</strong>&#58;

    - Описывают изменения состояния через типы и полезную нагрузку.

    - Пример&#58;

        ```javascript
        const increment = () => ({ type: 'INCREMENT' });
        ```

1. <strong>Редьюсеры (</strong><code>Reducers</code><strong>)</strong>&#58;

    - Функции, которые описывают, как состояние изменяется в ответ на действия.

    - Пример&#58;

        ```javascript
        const counter = (state = 0, action) => {
          switch (action.type) {
            case 'INCREMENT':
              return state + 1;
            default:
              return state;
          }
        };
        ```

1. <strong>Хранилище (</strong><code>Store</code><strong>)</strong>&#58;

    - Хранит состояние приложения и предоставляет методы для доступа к состоянию и отправки действий.

    - Пример&#58;

        ```javascript
        import { createStore } from 'redux';
        const store = createStore(counter);
        ```

1. <strong>Контейнерные компоненты (</strong><code>Container Components</code><strong>)</strong>&#58;

    - Соединяют компоненты React с Redux-хранилищем с помощью <code>connect</code>.

    - Пример&#58;

        ```javascript
        import { connect } from 'react-redux';

        const mapStateToProps = (state) => ({ count: state });
        const mapDispatchToProps = { increment };

        export default connect(mapStateToProps, mapDispatchToProps)(CounterComponent);
        ```

1. <code>Thunk Middleware</code>&#58;

    - Позволяет писать действия, которые возвращают функции вместо объектов, для работы с асинхронными операциями.

    - Пример&#58;

        ```javascript
        import { thunk } from 'redux-thunk';
        import { applyMiddleware, createStore } from 'redux';

        const store = createStore(rootReducer, applyMiddleware(thunk));
        ```

1. <strong>Селекторы (</strong><code>Selectors</code><strong>)</strong>&#58;

    - Функции для выборки данных из состояния, повышают читаемость и повторное использование кода.

    - Пример&#58;

        ```javascript
        const getCount = (state) => state.counter;
        ```

Популярные паттерны использования Redux включают действия, редьюсеры, хранилище, контейнерные компоненты, thunk middleware и селекторы. Эти паттерны помогают структурировать и управлять состоянием приложения эффективно.

:::note[Ссылки для изучения]

1. [Redux: однонаправленный поток actions, reducers и store](https://reactdev.ru/libs/redux/basics/DataFlow/)
   :::

---

## <strong>Какие альтернативы</strong> <code>Redux</code> <strong>для управления состоянием в React-приложениях?</strong> [#q-14bee738d69b81a0be51c85c58df6c04]

Альтернативы <code>Redux</code> для управления состоянием в React-приложениях&#58;

{/* prettier-ignore */}
1. <code>MobX</code>&#58;

    - Реактивное управление состоянием с акцентом на наблюдаемые данные и автоматические реакции.

    - Пример&#58;

        ```javascript
        import { observable, action } from 'mobx';
        import { observer } from 'mobx-react';
        ```

1. <code>Recoil</code>&#58;

    - Recoil использует атомы и селекторы, но его репозиторий архивирован в январе 2025 года. Это исторический пример, а не рекомендация для нового проекта.

    - Пример&#58;

        ```javascript
        import { RecoilRoot, atom, useRecoilState } from 'recoil';
        ```

1. <code>Zustand</code>&#58;

    - Легковесная и гибкая библиотека для управления состоянием.

    - Пример&#58;

        ```javascript
        import { create } from 'zustand';
        const useStore = create(set => ({
          count: 0,
          increment: () => set(state => ({ count: state.count + 1 }))
        }));
        ```

1. <code>Context API</code>&#58;

    - Встроенный механизм для управления глобальным состоянием с помощью контекста.

    - Пример&#58;

        ```jsx
        import { createContext, useContext, useState } from 'react';
        const MyContext = createContext();
        const MyProvider = ({ children }) => {
          const [state, setState] = useState(0);
          return <MyContext.Provider value={{ state, setState }}>{children}</MyContext.Provider>;
        };
        ```

1. <code>XState</code>&#58;

    - Управление состоянием с использованием конечных автоматов и диаграмм состояний.

    - Схематичный пример старого API XState 4. В XState 5 используют createMachine или setup; useMachine вызывают внутри компонента или пользовательского хука&#58;

        ```javascript
        import { Machine } from 'xstate';
        import { useMachine } from '@xstate/react';
        const toggleMachine = Machine({ /* состояние машины */ });
        const [state, send] = useMachine(toggleMachine);
        ```

1. <code>React Query</code>&#58;

    - Специализируется на управлении состоянием данных, извлекаемых из серверов.

    - Пример для React Query 3; useQuery вызывается внутри компонента или пользовательского хука. В TanStack Query 5 используется объект параметров&#58;

        ```javascript
        import { useQuery } from 'react-query';
        const { data, error, isLoading } = useQuery('data', fetchData);
        ```

Альтернативы Redux для управления состоянием в React-приложениях включают MobX, Recoil, Zustand, Context API, XState и React Query. Эти библиотеки и инструменты предлагают разные подходы и функциональные возможности для управления состоянием.

:::note[Ссылки для изучения]

1. [Zustand: хранилище состояния и подключение React-компонентов](https://reactdev.ru/libs/zustand/getting-started/introduction/)
   :::

---

## Когда useReducer лучше useState? [#q-transfer-0449]

`useReducer` удобнее, когда состояние меняется через несколько связанных переходов, следующие значения зависят от предыдущих, а правила обновления разбросались по обработчикам. Reducer принимает state и action и возвращает новое состояние, поэтому переходы можно читать и тестировать как чистую функцию. Это полезно для сложной формы, wizard или state machine. Для одного независимого boolean или строки `useState` проще. Reducer не делает состояние глобальным и не уменьшает render автоматически; его ценность состоит в явной модели переходов. Побочные эффекты выполняют вне reducer.

:::note[Ссылки для изучения]

1. [Когда выделять логику состояния в useReducer](https://reactdev.ru/learn/extracting-state-logic-into-a-reducer/)
   :::

---

## По каким признакам приложению нужен внешний стейт-менеджер? [#q-transfer-0450]

Внешний state manager оправдан, если одно клиентское состояние читают и изменяют далёкие части дерева, нужны сложные переходы, middleware, time-travel или единая диагностика. До выбора отделяют server state: запросы, кеш, дедупликацию и инвалидирование лучше часто решает специализированная библиотека. Локальные поля формы, hover и открытие модалки оставляют рядом с компонентом. Context подходит редко меняющимся зависимостям, но частые широкие обновления требуют аккуратного разделения. Решение принимают по владельцу данных, частоте обновлений и реальным проблемам отладки. Дополнительная инфраструктура должна окупать сериализацию, boilerplate и обучение команды.

:::note[Ссылки для изучения]

1. [Как разделить фронтенд на модули: раздел «Где хранить состояние приложения?»](https://habr.com/ru/companies/rwb/articles/1079970/)
   :::

---

## <strong>Что такое контекст (</strong><code>context</code><strong>) в React и для чего он используется?</strong> [#q-14bee738d69b8164a383e043874dd796]

<strong>Контекст (</strong>
<code>Context</code>
<strong>)</strong> — это механизм, который позволяет передавать данные через
дерево компонентов без необходимости передавать пропсы на каждом уровне.

#### Основные характеристики&#58;

{/* prettier-ignore */}
1. <strong>Обмен данными между компонентами</strong>&#58;

    - Используется для обмена данными между компонентами, которые находятся на разных уровнях вложенности.

1. <strong>Создание и использование контекста</strong>&#58;

    - Создается с помощью <code>React&#46;createContext</code>.

    - Обеспечивает доступ к данным через компоненты <code>Provider</code> и <code>Consumer</code>.

#### Пример&#58;

```jsx
import React, { createContext, useContext } from "react";

const MyContext = createContext();

const MyProvider = ({ children }) => {
  const value = "Hello, World!";
  return <MyContext.Provider value={value}>{children}</MyContext.Provider>;
};

const MyComponent = () => {
  const value = useContext(MyContext);
  return <div>{value}</div>;
};

const App = () => (
  <MyProvider>
    <MyComponent />
  </MyProvider>
);

export default App;
```

Контекст в React используется для передачи данных через дерево компонентов, избегая необходимости прокидывать пропсы на каждом уровне.

:::note[Ссылки для изучения]

1. [Context: создание, провайдер и чтение через useContext](https://reactdev.ru/learn/passing-data-deeply-with-context/)
2. [Context и useContext для общих данных. Ulbi TV, с 2:38:30](https://www.youtube.com/watch?v=GNrdg3PzpJQ&t=9510s)

:::

---

## <strong>Как работает механизм "контекста" (</strong><code>context</code><strong>) для передачи данных?</strong> [#q-14bee738d69b81069d3def5a4a244346]

<strong>Контекст (</strong>
<code>Context</code>
<strong>)</strong> — это механизм, который позволяет передавать данные через
дерево компонентов без необходимости передавать пропсы на каждом уровне.

#### Основные шаги&#58;

{/* prettier-ignore */}
1. <strong>Создание контекста</strong>&#58;

    - Создайте контекст с помощью <code>React&#46;createContext</code>.

    ```javascript
    const MyContext = React.createContext();
    ```

1. <strong>Обертка компонентов в Provider</strong>&#58;

    - Используйте компонент <code>Provider</code> для обертки тех компонентов, которые должны иметь доступ к контексту. Укажите значение, которое должно быть передано через контекст.

    ```jsx
    <MyContext.Provider value={/* значение */}>
      {/* дочерние компоненты */}
    </MyContext.Provider>
    ```

1. <strong>Потребление контекста</strong>&#58;

    - Компоненты, которые должны получать данные из контекста, могут использовать компонент <code>Consumer</code> или хук <code>useContext</code>.

    ```javascript
    // Использование хука useContext
    const value = useContext(MyContext);
    ```

#### Пример&#58;

```jsx
import React, { createContext, useContext } from "react";

// Создание контекста
const MyContext = createContext();

// Компонент Provider
const MyProvider = ({ children }) => {
  const value = "Hello, World!";
  return <MyContext.Provider value={value}>{children}</MyContext.Provider>;
};

// Компонент Consumer с хуком useContext
const MyComponent = () => {
  const value = useContext(MyContext);
  return <div>{value}</div>;
};

// Основное приложение
const App = () => (
  <MyProvider>
    <MyComponent />
  </MyProvider>
);

export default App;
```

Контекст в React позволяет передавать данные через дерево компонентов с помощью компонентов <code>Provider</code> и <code>Consumer</code>, а также хука <code>useContext</code>, упрощая обмен данными между компонентами на разных уровнях вложенности.

:::note[Ссылки для изучения]

1. [Context: создание, провайдер и чтение через useContext](https://reactdev.ru/learn/passing-data-deeply-with-context/)
2. [Context и useContext для общих данных. Ulbi TV, с 2:38:30](https://www.youtube.com/watch?v=GNrdg3PzpJQ&t=9510s)

:::

---

## <strong>Что такое "передача данных через контекст" (</strong><code>context passing</code><strong>) в React?</strong> [#q-14bee738d69b81c790a8e10936de08ef]

<strong>Передача данных через контекст</strong> — это механизм, который
позволяет передавать данные напрямую через дерево компонентов без необходимости
передавать пропсы на каждом уровне.

#### Основные шаги&#58;

{/* prettier-ignore */}
1. <strong>Создание контекста</strong>&#58;

    - Создайте контекст с помощью <code>React&#46;createContext</code>.

    ```javascript
    const MyContext = React.createContext();
    ```

1. <strong>Использование Provider</strong>&#58;

    - Оберните дерево компонентов в <code>MyContext&#46;Provider</code> и передайте значение контекста.

    ```jsx
    <MyContext.Provider value={/* значение */}>
      {/* дочерние компоненты */}
    </MyContext.Provider>
    ```

1. <strong>Использование Consumer или useContext</strong>&#58;

    - Компоненты, которые должны получать данные из контекста, используют <code>MyContext&#46;Consumer</code> или хук <code>useContext</code>.

    ```javascript
    const value = useContext(MyContext);
    ```

#### Пример&#58;

```jsx
import React, { createContext, useContext } from "react";

// Создание контекста
const MyContext = createContext();

// Компонент Provider
const MyProvider = ({ children }) => {
  const value = "Hello, World!";
  return <MyContext.Provider value={value}>{children}</MyContext.Provider>;
};

// Компонент Consumer с хуком useContext
const MyComponent = () => {
  const value = useContext(MyContext);
  return <div>{value}</div>;
};

// Основное приложение
const App = () => (
  <MyProvider>
    <MyComponent />
  </MyProvider>
);

export default App;
```

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

:::note[Ссылки для изучения]

1. [Context: создание, провайдер и чтение через useContext](https://reactdev.ru/learn/passing-data-deeply-with-context/)
2. [Context и useContext для общих данных. Ulbi TV, с 2:38:30](https://www.youtube.com/watch?v=GNrdg3PzpJQ&t=9510s)

:::
