{"id":14276,"url":"\/distributions\/14276\/click?bit=1&hash=721b78297d313f451e61a17537482715c74771bae8c8ce438ed30c5ac3bb4196","title":"\u0418\u043d\u0432\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u0439 \u0442\u043e\u0432\u0430\u0440 \u0438\u043b\u0438 \u0443\u0441\u043b\u0443\u0433\u0443 \u0431\u0435\u0437 \u0431\u0438\u0440\u0436\u0438","buttonText":"","imageUuid":""}

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

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

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

Оглавление

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Родительский компонент назначает данные 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 уровня иерархии не составляет большой проблемы.

0
Комментарии
-3 комментариев
Раскрывать всегда