HTML Diff
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>Передача данных в контекст. Работает так: оборачиваем нужные компоненты в компонент контекста &lt;UserContext.Provider&gt; и передаем туда нужные данные в проп value:</p>
6 <li><p>Передача данных в контекст. Работает так: оборачиваем нужные компоненты в компонент контекста &lt;UserContext.Provider&gt; и передаем туда нужные данные в проп 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>В компоненте &lt;App/&gt; определено состояние с текущей компанией и метод для её изменения.</li>
17 <li>В компоненте &lt;App/&gt; определено состояние с текущей компанией и метод для её изменения.</li>
18 <li>Компоненты &lt;CompanyNameComponent/&gt; и &lt;CompanyAddressComponent/&gt; получают данные из контекста и отображают название и адрес текущей компании.</li>
18 <li>Компоненты &lt;CompanyNameComponent/&gt; и &lt;CompanyAddressComponent/&gt; получают данные из контекста и отображают название и адрес текущей компании.</li>
19 <li>&lt;CompanySwitcher/&gt; позволяет переключать между компаниями, обновляя состояние и тем самым меняя отображаемые данные на странице.</li>
19 <li>&lt;CompanySwitcher/&gt; позволяет переключать между компаниями, обновляя состояние и тем самым меняя отображаемые данные на странице.</li>
20 </ol><p>При изменении данных в контексте компоненты, которые зависят от этих данных, будут перерисованы. Это происходит благодаря тому, что состояние, хранящее данные контекста, изменяется в компоненте-родителе (&lt;App/&gt;), и новое значение контекста передается вниз через провайдер. Это удобно для таких задач, где изменение состояния напрямую влияет на всё приложение (например переключение темы, языка, пользователя и тд).</p>
20 </ol><p>При изменении данных в контексте компоненты, которые зависят от этих данных, будут перерисованы. Это происходит благодаря тому, что состояние, хранящее данные контекста, изменяется в компоненте-родителе (&lt;App/&gt;), и новое значение контекста передается вниз через провайдер. Это удобно для таких задач, где изменение состояния напрямую влияет на всё приложение (например переключение темы, языка, пользователя и тд).</p>
21 - <p><a>https://codepen.io/hexlet/pen/YzmVpmr</a></p>
21 + <p><a>Попрактиковаться</a></p>