Руководство по React Context и useContext ()
Перевод статьи
Контекст React предоставляет данные компонентам независимо от того, насколько глубоко они находятся в дереве компонентов.
В этом посте вы узнаете, как использовать концепцию контекста в React.
Оглавление
- Как использовать контекст
- Когда он вам пригодится?
- Пример использования (имя пользователя)
- Контекст на помощь
- Когда контекст меняется
- Обновление контекста
- Вывод
1 Как использовать контекст
Для использования контекста в React требуется 3 простых шага: создание контекста(A), предоставление контекста(Б) и использование контекста(В).
A.Создадим контекст
Заводская функция принимает один необязательный аргумент: 'Любое значение'
Б. Предоставление контекста
Компонент Context.Provider — доступный в экземпляре контекста, используется для предоставления контекста его дочерним компонентам, независимо от их глубины.
Опять же, здесь важно то, что все компоненты, которые позже захотят использовать контекст, должны быть заключены в компонент провайдера.
В. Использование контекста
Использование контекста может быть выполнено двумя способами. Первый способ — это использовать хук useContext (Context)
Хук также гарантирует повторный рендеринг компонента при изменении значения контекста
Второй способ — использовать функцию рендеринга, предоставленную в качестве дочернего для специального компонента Context.Consumer, доступного в экземпляре контекста:
Вы можете иметь столько дочерних компонентов, сколько хотите для одного контекста. Если значение контекста изменяется (путем изменения свойства value провайдера (), то все дочерние компоненты немедленно уведомляются и повторно обрабатываются. Если дочерний компонент не заключен внутри провайдера, но все же пытается получить доступ к значению контекста (используя useContext (Context) или) , то значение контекста будет аргументом значения по умолчанию, предоставленным createContext (defaultValue) фабричная функция, создавшая контекст.
2 Когда он вам пригодится?
Основная идея использования контекста — предоставить вашим компонентам доступ к некоторым глобальным данным и повторный рендеринг при изменении этих глобальных данных. Контекст решает проблему сверления реквизита: когда вам нужно передать реквизиты от родителей детям.
Вы можете держать внутри контекста:
- Глобальное состояние приложения
- Тема приложения
- Конфигурация приложения
- Аутентификация пользователя
- Пользовательские настройки
- Предпочтительный язык
- Набор услуг
С другой стороны, вы должны хорошо подумать, прежде чем принимать решение об использовании контекста в своем приложении.
- Во-первых, интеграция контекста добавляет сложности. Создание контекста, обертывание всего в провайдере, использование useContext () в каждом дочернем компоненте — это увеличивает сложность.
- Во-вторых, добавление контекста затрудняет модульное тестирование компонентов. Во время модульного тестирования вам придется заключить потребительские компоненты в поставщик контекста. Включая компоненты, на которые косвенно влияет контекст — родителей дочерних компонентов контекста!
3 Пример использования (имя пользователя)
Самый простой способ передать данные от родителя к дочернему компоненту — это когда родитель назначает реквизиты своему дочернему компоненту
Родительский компонент назначает данные userName своему дочернему компоненту с помощью свойства userName.
Это обычный способ передачи данных с использованием реквизита. Вы можете использовать этот подход без проблем. Ситуация меняется, когда дочерний компонент не является прямым потомком , но содержится в нескольких предках. Например, предположим, что компонент (тот, у которого есть глобальные данные userName) отображает компонент , который, в свою очередь, отображает компонент
, который, в свою очередь, в конечном итоге отображает компонент (который хотел бы получить доступ к имени пользователя).Посмотрим как это будет выглядеть
Вы можете видеть проблему: поскольку компонент отображается глубоко в дереве, и все родительские компоненты ( и
) должны передавать свойство userName.Эта проблема также известна как Буровая установка.
Контекст React — возможное решение. Давайте посмотрим, как его применить в следующем разделе.
4 Контекст на помощь
Напоминаем, что для применения контекста React требуются 3 участника: контекст, провайдер, извлеченный из контекста, и дочерний компонент.
Вот как будет выглядеть пример приложения при применении к нему контекста
Во-первых, const UserContext = createContext ('Unknown') создает контекст, в котором будет храниться информация об имени пользователя.
Во-вторых, внутри компонента дочерние компоненты приложения заключены в контекст пользователя: . Обратите внимание, что свойство value компонента поставщика важно: именно так вы устанавливаете значение контекста.
Наконец, становится потребителем контекста с помощью встроенной ловушки useContext (UserContext). Хук вызывается с контекстом в качестве аргумента и возвращает значение имени пользователя.
Промежуточные компоненты и
не должны передавать свойство userName. В этом большое преимущество контекста — он снимает бремя передачи данных через промежуточные компоненты.
5 Когда контекст меняется
Когда значение контекста изменяется путем изменения свойства значения поставщика контекста (), тогда все его потребители уведомляются и повторно обрабатываются. Например, если я изменю имя пользователя с «Дэн Абрамов» на «Дэн, Дэн Абрамов», то потребитель немедленно выполнит повторный рендеринг, чтобы отобразить последнее значение контекста
6 Обновление контекста
React Context API по умолчанию не имеет состояния и не предоставляет специальный метод для обновления значения контекста из компонентов-потребителей.
Но это можно легко реализовать, интегрировав механизм управления состоянием (например, хуки useState () или useReducer ()) и предоставив функцию обновления прямо в контексте рядом с самим значением. В следующем примере компонент использует ловушку useState () для управления значением контекста.
потребитель считывает значение контекста, из которого извлекаются userName и setUserName. Затем потребитель может обновить значение контекста, вызвав функцию обновления setUserName (newContextValue)
— еще один потребитель контекста. Когда обновляет контекст, этот компонент также обновляется.
Обратите внимание, что запоминает значение контекста. Мемоизация сохраняет объект значения контекста одним и тем же до тех пор, пока userName остается неизменным, предотвращая повторную визуализацию потребителей каждый раз, когда повторно отображается . В противном случае, без мемоизации, const value = {userName, setUserName} создаст разные экземпляры объекта во время повторного рендеринга , инициируя повторный рендеринг в потребителях контекста.
7 Вывод
Контекст в React — это концепция, которая позволяет вам снабжать дочерние компоненты глобальными данными, независимо от того, насколько глубоко они находятся в дереве компонентов.
Для использования контекста требуется 3 шага: создание, предоставление и использование контекста. При интеграции контекста в ваше приложение учтите, что он значительно усложняет его. Иногда «прокинуть» пропсы через 2-3 уровня иерархии не составляет большой проблемы.
Спасибо Дмитрий Павлютин