Основные компоненты контейнера в React

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

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

Преимущества:

  • Извлекая данные один раз, они могут быть разделены между всеми дочерними элементами, переданными внутри контейнера.
  • Он больше склоняется к разделению задач управления данными и представления данных в пользовательском интерфейсе.
  • Это повышает тестируемость, облегчая отдельное тестирование логики компонента контейнера, связанного с данными, и поведения рендеринга презентационного компонента.

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

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

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

В следующем примере кода наша цель — отобразить на экране информацию, специфичную для пользователя. Эта информация будет определяться userId и будет включать в себя такие сведения, как имя пользователя, возраст, цвет волос и хобби. В качестве наивного подхода вы бы сделали что-то вроде этого, скажем, вы создали компонент, выполняющий некоторый вызов API GET, поддерживающий состояние пользователя и возвращающий некоторый JSX, который в конечном итоге будет отображаться на экране.

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

  • Во-первых, в одном компоненте объединены все задачи, включая извлечение данных, управление данными и визуализацию данных.
  • Во-вторых, тестирование таких компонентов может превратиться в громоздкий процесс из-за потенциальной сложности компонентов.
  • Наконец, этот подход нарушает принцип разделения задач, согласно которому отдельные аспекты функциональности должны быть разделены.

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

App.js

Этот корневой компонент или, в вашем случае, может быть, он может действовать как родительский компонент, который может выполнять некоторую операцию, чтобы получить значение userId и передать значение компоненту GenericUser.

GenericUser.jsx

Этот компонент оборачивает компонент UserInfo в GenericUserLoader и передает значение userId в качестве реквизита компоненту-контейнеру GenericUserLoader. UserInfo теперь является дочерним элементом компонента контейнера.

Примечание. Свойство Children в GenericUserLoader очень полезно при передаче свойства компоненту UserInfo. Смущенный ? Не волнуйтесь, мы подробно рассмотрим это в компоненте GenericUserLoader.

UserInfo.jsx

Совершенно ясно, что делает этот компонент, он принимает пользователя как prop и отображает информацию о пользователе на экране. Здесь интересно отметить, что этот компонент не знает, откуда он берет пользовательские данные. Его основная задача — корректно отображать на странице все данные, переданные в качестве реквизита.

GenericUserLoader.jsx [компонент-контейнер]

GenericUserLoader загружает пользовательские данные из API и передает состояние своим дочерним элементам с загруженными пользовательскими данными. Разберем пошагово:

Компонент принимает два реквизита: userId и children. Свойство userId представляет идентификатор пользователя, которого вы хотите получить, а дочерние элементы — это компоненты или элементы, которые должны отображаться на экране с использованием полученных пользовательских данных.

В функции обратного вызова используется асинхронный IIFE (выражение функции с немедленным вызовом), чтобы сделать HTTP-запрос GET к конечной точке /users/${userId} с использованием библиотеки axios. Ответ на вызов API используется для обновления состояния пользователя с помощью функции setUser.

А теперь самое интересное 💡:

  • Оператор return отображает дочерние компоненты, но с пользовательскими данными, переданными в качестве опоры.
  • React.Children.map используется для перебора каждого дочернего элемента, переданного компоненту GenericUserLoader. В этом случае есть только один дочерний элемент, то есть [компонент UserInfo].
  • Для каждого дочернего элемента он проверяет, является ли он допустимым элементом React. Если он действителен и данные user существуют, он использует React.cloneElement для создания нового экземпляра дочернего элемента с переданным ему реквизитом user.
  • Если дочерний элемент не является допустимым элементом или отсутствуют пользовательские данные, он возвращается как есть.

Вывод:

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

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

Помните о силе компонентов Container и стремитесь создать бесшовный и эффективный пользовательский интерфейс.

Удачного кодирования!

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

Приветствую немного облегчения жизни разработчика!

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