Контекст - это новая функция, выпущенная в официальном API вместе с React 16.3.0. На первый взгляд очень простой, он очень легко раскрывает весь свой потенциал с небольшим воображением.

Я экспериментирую с функцией контекста в React с момента его первого официального выпуска 16.3, а теперь, с новым выпуском 16.6, я определенно больше не могу без него обходиться. Я уже написал несколько библиотек, использующих эту функцию, и контекст всегда упрощает взаимодействие между компонентами.

В этой статье я попытаюсь объяснить вам, как вы можете использовать Context в своем собственном приложении React.

Внедрение зависимости

Функция контекста - это не что иное, как способ внедрения зависимостей в компонент без использования свойств.

Иногда вам нужно обмениваться данными между несколькими связанными компонентами, такими как тема или ширина меток в форме. С React у вас раньше было 2 решения.

Первый способ заключался в передаче ваших данных от родителей детям с помощью свойств. Таким образом, ваши данные определяются в состоянии вашего корневого компонента и распространяются на дочерние компоненты с помощью свойств.

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

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

Проблема с этим вторым вариантом заключается в распространении различных значений в зависимости от положения вашего компонента в DOM.

Теперь Контекст есть!

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

С помощью контекста вы можете передавать информацию дочерним компонентам, основным дочерним компонентам и другим дочерним компонентам. Вы можете создать несколько раз один и тот же контекст с разными значениями, каждый компонент будет получать данные в зависимости от своего положения в DOM.

Тема

Первый вариант использования контекста, который вы часто видите, - это цветовая тема. С помощью контекста вы можете легко определить тему в корневом компоненте, и все компоненты могут иметь доступ к теме. Но мы можем пойти дальше.

Умные компоненты

Чтобы добавить настраиваемое поведение / дизайн, вы иногда создаете свои собственные компоненты Form, Label, Input, Select, которые являются оболочками вокруг формы элемента html по умолчанию, метки, ввода, выбора.

В этом примере каждая метка имеет имя класса, определяющее ширину метки, и метку для отображения текста перед вводом.

С помощью контекста вы можете позволить этим компонентам более эффективно взаимодействовать друг с другом. Например, компонент формы может предоставить контекст, чтобы указать, какое имя класса все дочерние ярлыки должны использовать. Или входные данные могут автоматически поглощать метку, предоставленную метке, если не указан заполнитель.

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

Это может сэкономить вам много кода, но самое лучшее еще впереди!

Сверху вниз или снизу вверх

Описанная выше стратегия основана на передаче данных сверху вниз. Родитель может передавать информацию детям. Но вы также можете использовать контекст для двустороннего общения.

Как только я увидел контекст, я вообразил библиотеку, чтобы мои компоненты появлялись постепенно. Используя счетчик, предоставленный родительским поставщиком, каждый дочерний элемент мог определить, когда пришла его очередь появиться.

Это был первый хороший шаг. Мне не нужно было размещать все анимированные элементы на одном уровне DOM.

Но, чтобы остановить приращение после последнего компонента, мне пришлось определить количество элементов в AnimatedGroup, потому что родитель не знает количество анимированных элементов, которыми он должен управлять - помните, что все анимированные элементы не являются прямыми дочерними элементами. . Я также мог позволить ему увеличиваться бесконечно, но это требовало ресурсов. Кроме того, мне нужно было определить индекс каждого AnimatedItem, чтобы знать, когда он должен появиться.

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

В то же время поставщик контекста может передавать данные, а также обратные вызовы.

Благодаря обратным вызовам и доступу к контексту повсюду теперь вы можете создавать общение снизу вверх. В предыдущем варианте использования AnimatedGroup могла предоставить функцию register. Каждому AnimatedItem достаточно вызвать этот метод, чтобы AnimatedGroup посчитала его и получила взамен индекс.

Таким образом, взаимодействие между AnimatedGroup и AnimatedItem становится следующим:

Вам больше не нужно определять itemNumber, поскольку при обратном вызове регистра, обеспечивающем контекст, AnimatedGroup знает количество смонтированных AnimatedItem. В то же время регистр возвратил индекс для каждого установленного AnimatedItem.

Код легче, а взаимодействие между AnimatedGroup и AnimatedItem умнее.

И это так хорошо работает, что я действительно опубликовал библиотеку. Пример библиотеки анимации - это всего лишь небольшой пример, показывающий, что Context может значительно автоматизировать взаимодействие между компонентами, которые вы создаете. Сила контекста только ограничивает ваше воображение!

Например, вы можете использовать второй обратный вызов, чтобы заметить поставщика, когда анимация AnimatedItem завершена, и поэтому анимировать компонент только тогда, когда предыдущий полностью отображается.

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

Если у вас есть какие-либо вопросы, не стесняйтесь размещать их ниже. И не забывайте хлопать в ладоши, если эта статья вам помогла.