3 added
3 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Передача данных через пропсы вниз по иерархии компонентов - это немного многословный, но простой механизм. Всегда видно, откуда пришли данные и как они попали внутрь, а компоненты легко переиспользовать, так как они зависят только от входных данных. Но бывают ситуации, когда передача пропсов не вписывается в то, как работает код.</p>
1
<p>Передача данных через пропсы вниз по иерархии компонентов - это немного многословный, но простой механизм. Всегда видно, откуда пришли данные и как они попали внутрь, а компоненты легко переиспользовать, так как они зависят только от входных данных. Но бывают ситуации, когда передача пропсов не вписывается в то, как работает код.</p>
2
<p>Возьмем для примера текущего пользователя. Часто данные пользователя нужны одновременно в разных частях страницы, причем в очень глубоких компонентах. Для этого придется передавать пользователя буквально по всей иерархии: даже там, где он не нужен компоненту. Единственная цель такой передачи - прокинуть данные до места назначения, пройдя по пути все промежуточные компоненты. Получается, что множество компонентов никак не используют пользователя, они просто передают их дальше по цепочке. В нашей ситуации данные пользователя глобальные. Они нужны сразу многим компонентам на разных уровнях иерархии. Для таких задач в React существует обходной путь.</p>
2
<p>Возьмем для примера текущего пользователя. Часто данные пользователя нужны одновременно в разных частях страницы, причем в очень глубоких компонентах. Для этого придется передавать пользователя буквально по всей иерархии: даже там, где он не нужен компоненту. Единственная цель такой передачи - прокинуть данные до места назначения, пройдя по пути все промежуточные компоненты. Получается, что множество компонентов никак не используют пользователя, они просто передают их дальше по цепочке. В нашей ситуации данные пользователя глобальные. Они нужны сразу многим компонентам на разных уровнях иерархии. Для таких задач в React существует обходной путь.</p>
3
<p>Context API - механизм, позволяющий сделать глобальные данные доступными из любого компонента напрямую, без прокидывания пропсов. Его использование сводится к трем шагам:</p>
3
<p>Context API - механизм, позволяющий сделать глобальные данные доступными из любого компонента напрямую, без прокидывания пропсов. Его использование сводится к трем шагам:</p>
4
<ol><li><p>Создание контекста:</p>
4
<ol><li><p>Создание контекста:</p>
5
</li>
5
</li>
6
<li><p>Передача данных в контекст. Работает так: оборачиваем нужные компоненты в компонент контекста <UserContext.Provider> и передаем туда нужные данные в проп value:</p>
6
<li><p>Передача данных в контекст. Работает так: оборачиваем нужные компоненты в компонент контекста <UserContext.Provider> и передаем туда нужные данные в проп value:</p>
7
</li>
7
</li>
8
<li><p>Получение данных из контекста. В компоненте, где нужны данные, нужно указать тип контекста с помощью статического свойства contextType. Реакт ищет ближайший провайдер этого контекста и берет из него значение. Поиск провайдера происходит вверх по дереву компонентов. Значение контекста будет доступно в this.context:</p>
8
<li><p>Получение данных из контекста. В компоненте, где нужны данные, нужно указать тип контекста с помощью статического свойства contextType. Реакт ищет ближайший провайдер этого контекста и берет из него значение. Поиск провайдера происходит вверх по дереву компонентов. Значение контекста будет доступно в this.context:</p>
9
</li>
9
</li>
10
-
</ol><p><a>https://codepen.io/hexlet/pen/abYVNZR</a></p>
10
+
</ol><p><a>Попрактиковаться</a></p>
11
<p>Еще один пример, где несколько компонентов используют данные из контекста:</p>
11
<p>Еще один пример, где несколько компонентов используют данные из контекста:</p>
12
-
<p><a>https://codepen.io/hexlet/pen/ZExaWVm</a></p>
12
+
<p><a>Попрактиковаться</a></p>
13
<p>В отличие от пропсов, изменение данных в контексте не приводит к перерисовке по умолчанию. Идеально, когда данные в контексте используются только для чтения. Изменяемые данные лучше хранить внутри состояния компонентов. Однако, если очень нужно, то реагировать на изменение контекста возможно, об этом подробнее можно прочитать в документации. В прикладном коде такая возможность используется редко, но на ней основаны разнообразные библиотеки.</p>
13
<p>В отличие от пропсов, изменение данных в контексте не приводит к перерисовке по умолчанию. Идеально, когда данные в контексте используются только для чтения. Изменяемые данные лучше хранить внутри состояния компонентов. Однако, если очень нужно, то реагировать на изменение контекста возможно, об этом подробнее можно прочитать в документации. В прикладном коде такая возможность используется редко, но на ней основаны разнообразные библиотеки.</p>
14
<p>Рассмотрим пример, когда контекст используется совместно с изменяемыми данными. Для этого расширим наш пример, добавив больше компаний и переключение между ними:</p>
14
<p>Рассмотрим пример, когда контекст используется совместно с изменяемыми данными. Для этого расширим наш пример, добавив больше компаний и переключение между ними:</p>
15
<p>Разберем пример:</p>
15
<p>Разберем пример:</p>
16
<ol><li>Мы создали контекст CompanyContext, который хранит информацию о нескольких компаниях, текущую выбранную компанию и функцию для изменения компании.</li>
16
<ol><li>Мы создали контекст CompanyContext, который хранит информацию о нескольких компаниях, текущую выбранную компанию и функцию для изменения компании.</li>
17
<li>В компоненте <App/> определено состояние с текущей компанией и метод для её изменения.</li>
17
<li>В компоненте <App/> определено состояние с текущей компанией и метод для её изменения.</li>
18
<li>Компоненты <CompanyNameComponent/> и <CompanyAddressComponent/> получают данные из контекста и отображают название и адрес текущей компании.</li>
18
<li>Компоненты <CompanyNameComponent/> и <CompanyAddressComponent/> получают данные из контекста и отображают название и адрес текущей компании.</li>
19
<li><CompanySwitcher/> позволяет переключать между компаниями, обновляя состояние и тем самым меняя отображаемые данные на странице.</li>
19
<li><CompanySwitcher/> позволяет переключать между компаниями, обновляя состояние и тем самым меняя отображаемые данные на странице.</li>
20
</ol><p>При изменении данных в контексте компоненты, которые зависят от этих данных, будут перерисованы. Это происходит благодаря тому, что состояние, хранящее данные контекста, изменяется в компоненте-родителе (<App/>), и новое значение контекста передается вниз через провайдер. Это удобно для таких задач, где изменение состояния напрямую влияет на всё приложение (например переключение темы, языка, пользователя и тд).</p>
20
</ol><p>При изменении данных в контексте компоненты, которые зависят от этих данных, будут перерисованы. Это происходит благодаря тому, что состояние, хранящее данные контекста, изменяется в компоненте-родителе (<App/>), и новое значение контекста передается вниз через провайдер. Это удобно для таких задач, где изменение состояния напрямую влияет на всё приложение (например переключение темы, языка, пользователя и тд).</p>
21
-
<p><a>https://codepen.io/hexlet/pen/YzmVpmr</a></p>
21
+
<p><a>Попрактиковаться</a></p>