Руководство по React Context и useContext ()

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

В этом посте вы узнаете, как использовать концепцию контекста в React.

Оглавление

  1. Как использовать контекст
  2. Когда он вам пригодится?
  3. Пример использования (имя пользователя)
  4. Контекст на помощь
  5. Когда контекст меняется
  6. Обновление контекста
  7. Вывод

1 Как использовать контекст

Для использования контекста в React требуется 3 простых шага: создание контекста(A), предоставление контекста(Б) и использование контекста(В).

A.Создадим контекст

Встроенная фабричная функция createContext (по умолчанию) создает экземпляр контекста
Встроенная фабричная функция createContext (по умолчанию) создает экземпляр контекста

Заводская функция принимает один необязательный аргумент: 'Любое значение'

Б. Предоставление контекста

Компонент Context.Provider — доступный в экземпляре контекста, используется для предоставления контекста его дочерним компонентам, независимо от их глубины.

Чтобы установить значение контекста, используйте свойство value, доступное в <Context.Provider value = {value} />
Чтобы установить значение контекста, используйте свойство value, доступное в <Context.Provider value = {value} />

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

В. Использование контекста

Использование контекста может быть выполнено двумя способами. Первый способ — это использовать хук useContext (Context)

Хук возвращает значение контекста: value = useContext (Context)
Хук возвращает значение контекста: value = useContext (Context)

Хук также гарантирует повторный рендеринг компонента при изменении значения контекста

Второй способ — использовать функцию рендеринга, предоставленную в качестве дочернего для специального компонента Context.Consumer, доступного в экземпляре контекста:

Опять же, в случае, если значение контекста изменится - повторно отрендерит свою функцию рендеринга.
Опять же, в случае, если значение контекста изменится - повторно отрендерит свою функцию рендеринга.
Руководство по React Context и useContext ()

Вы можете иметь столько дочерних компонентов, сколько хотите для одного контекста. Если значение контекста изменяется (путем изменения свойства value провайдера (), то все дочерние компоненты немедленно уведомляются и повторно обрабатываются. Если дочерний компонент не заключен внутри провайдера, но все же пытается получить доступ к значению контекста (используя useContext (Context) или) , то значение контекста будет аргументом значения по умолчанию, предоставленным createContext (defaultValue) фабричная функция, создавшая контекст.

2 Когда он вам пригодится?

Основная идея использования контекста — предоставить вашим компонентам доступ к некоторым глобальным данным и повторный рендеринг при изменении этих глобальных данных. Контекст решает проблему сверления реквизита: когда вам нужно передать реквизиты от родителей детям.

Вы можете держать внутри контекста:

  • Глобальное состояние приложения
  • Тема приложения
  • Конфигурация приложения
  • Аутентификация пользователя
  • Пользовательские настройки
  • Предпочтительный язык
  • Набор услуг

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

  • Во-первых, интеграция контекста добавляет сложности. Создание контекста, обертывание всего в провайдере, использование useContext () в каждом дочернем компоненте — это увеличивает сложность.
  • Во-вторых, добавление контекста затрудняет модульное тестирование компонентов. Во время модульного тестирования вам придется заключить потребительские компоненты в поставщик контекста. Включая компоненты, на которые косвенно влияет контекст — родителей дочерних компонентов контекста!

3 Пример использования (имя пользователя)

Самый простой способ передать данные от родителя к дочернему компоненту — это когда родитель назначает реквизиты своему дочернему компоненту

т.к. пишу на TS - Props обьявил ранее и назначил тип имени - строкой
т.к. пишу на TS - Props обьявил ранее и назначил тип имени - строкой

Родительский компонент назначает данные userName своему дочернему компоненту с помощью свойства userName.

Это обычный способ передачи данных с использованием реквизита. Вы можете использовать этот подход без проблем. Ситуация меняется, когда дочерний компонент не является прямым потомком , но содержится в нескольких предках. Например, предположим, что компонент (тот, у которого есть глобальные данные userName) отображает компонент , который, в свою очередь, отображает компонент

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

Посмотрим как это будет выглядеть

Руководство по React Context и useContext ()

Вы можете видеть проблему: поскольку компонент отображается глубоко в дереве, и все родительские компоненты ( и

) должны передавать свойство userName.

Эта проблема также известна как Буровая установка.

Контекст React — возможное решение. Давайте посмотрим, как его применить в следующем разделе.

4 Контекст на помощь

Напоминаем, что для применения контекста React требуются 3 участника: контекст, провайдер, извлеченный из контекста, и дочерний компонент.

Вот как будет выглядеть пример приложения при применении к нему контекста

Руководство по React Context и useContext ()

Во-первых, const UserContext = createContext ('Unknown') создает контекст, в котором будет храниться информация об имени пользователя.

Во-вторых, внутри компонента дочерние компоненты приложения заключены в контекст пользователя: . Обратите внимание, что свойство value компонента поставщика важно: именно так вы устанавливаете значение контекста.

Наконец, становится потребителем контекста с помощью встроенной ловушки useContext (UserContext). Хук вызывается с контекстом в качестве аргумента и возвращает значение имени пользователя.

Промежуточные компоненты и

не должны передавать свойство userName. В этом большое преимущество контекста — он снимает бремя передачи данных через промежуточные компоненты.

5 Когда контекст меняется

Когда значение контекста изменяется путем изменения свойства значения поставщика контекста (), тогда все его потребители уведомляются и повторно обрабатываются. Например, если я изменю имя пользователя с «Дэн Абрамов» на «Дэн, Дэн Абрамов», то потребитель немедленно выполнит повторный рендеринг, чтобы отобразить последнее значение контекста

Руководство по React Context и useContext ()

6 Обновление контекста

React Context API по умолчанию не имеет состояния и не предоставляет специальный метод для обновления значения контекста из компонентов-потребителей.

Но это можно легко реализовать, интегрировав механизм управления состоянием (например, хуки useState () или useReducer ()) и предоставив функцию обновления прямо в контексте рядом с самим значением. В следующем примере компонент использует ловушку useState () для управления значением контекста.

Руководство по React Context и useContext ()

потребитель считывает значение контекста, из которого извлекаются userName и setUserName. Затем потребитель может обновить значение контекста, вызвав функцию обновления setUserName (newContextValue)

— еще один потребитель контекста. Когда обновляет контекст, этот компонент также обновляется.

Обратите внимание, что запоминает значение контекста. Мемоизация сохраняет объект значения контекста одним и тем же до тех пор, пока userName остается неизменным, предотвращая повторную визуализацию потребителей каждый раз, когда повторно отображается . В противном случае, без мемоизации, const value = {userName, setUserName} создаст разные экземпляры объекта во время повторного рендеринга , инициируя повторный рендеринг в потребителях контекста.

7 Вывод

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

Для использования контекста требуется 3 шага: создание, предоставление и использование контекста. При интеграции контекста в ваше приложение учтите, что он значительно усложняет его. Иногда «прокинуть» пропсы через 2-3 уровня иерархии не составляет большой проблемы.

2
Начать дискуссию