Введение в шаблоны проектирования Container-Presenter в React
9 мая 2022 г.Шаблон проектирования Container-Presenter был первоначально придуман Дэном Абрамовым и получил широкое распространение благодаря довольно чистой реализации Разделение проблем , а также элегантный способ работы со сложной логикой с отслеживанием состояния и согласованность, которую он поддерживает во всем приложении.
Философия шаблона Container-Presenter
Философия шаблона проектирования Container-Presenter довольно проста; Компоненты делятся на 2 категории на основе нескольких нечетко определенных факторов:
- Компоненты контейнера
- Презентация/Презентационные компоненты
Как различать компоненты контейнера и презентатора
Важно понимать, что различие между презентационными компонентами и контейнерами следует проводить не с технической точки зрения, а скорее с точки зрения цели, которой они призваны служить.
По словам Дэна Абрамова, существует некоторое непонимание между различными общими техническими различиями, которое не обязательно должно быть движущим фактором. при принятии решения о том, что является компонентом контейнера/презентатора, а что нет:
С состоянием и без состояния
Некоторые компоненты используют метод React setState(), а некоторые нет. Хотя компоненты-контейнеры, как правило, сохраняют состояние, а презентационные компоненты, как правило, не имеют состояния, это не является жестким правилом. Презентационные компоненты могут иметь состояние, а контейнеры также могут быть без состояния.
Классы и функции
*Начиная с React 0.14 компоненты могут быть объявлены как как классы и как функции. Функциональные компоненты проще определить, но им не хватает некоторых функций, доступных в настоящее время только компонентам класса. Некоторые из этих ограничений могут исчезнуть в будущем, но они существуют сегодня. Поскольку функциональные компоненты легче понять, я предлагаю вам использовать их, если вам не нужно состояние, ловушки жизненного цикла или оптимизация производительности, которые в настоящее время доступны только для компонентов класса. *
Чистый и нечистый
Говорят, что компонент чистый, если он гарантированно возвращает один и тот же результат при одинаковых реквизитах и состоянии. Чистые компоненты могут быть определены и как классы, и как функции, и могут быть как с состоянием, так и без него. Еще одним важным аспектом чистых компонентов является то, что они не полагаются на глубокие мутации свойств или состояния, поэтому производительность их рендеринга можно оптимизировать путем поверхностного сравнения в их [shouldComponentUpdate() хуке] (https://facebook.github. io/react/docs/pure-render-mixin.html). В настоящее время только классы могут определять shouldComponentUpdate(), но это может измениться в будущем.
Он стремится прояснить, что существует разница между вышеупомянутыми дихотомиями и тем, где на самом деле проводится линия между тем, что составляет презентацию или компонент-контейнер (техническая против целевой ссылки).
Он сделал определенные выводы из своего опыта, например, тот факт, что Презентационные компоненты, как правило, являются чистыми функциями без состояния, в то время как Контейнерные компоненты, как правило, являются чистыми классами с сохранением состояния:
И презентационные компоненты, и контейнеры могут попасть в любую из этих групп. По моему опыту, презентационные компоненты, как правило, являются чистыми функциями без состояния, а контейнеры — чистыми классами с состоянием. Однако это не правило, а наблюдение, и я видел прямо противоположные случаи, которые имели смысл в конкретных обстоятельствах.
В конечном счете, его последний комментарий по этому вопросу подтверждает тот факт, что линия между компонентами «Презентация» и «Контейнер» должна проводиться всякий раз, когда цель определенного компонента или блока компонентов ясна:
Не воспринимайте разделение презентационных и контейнерных компонентов как догму. Иногда это не имеет значения или трудно провести черту. Если вы не уверены, должен ли конкретный компонент быть презентационным или контейнерным, возможно, еще слишком рано принимать решение. Не парься!
Преимущества шаблона Container-Presenter
- Хорошее разделение интересов
- Простота повторного использования компонентов во всем приложении, что не только ускоряет время разработки, но и улучшает визуальную согласованность между представлениями/макетами.
- Более последовательные приложения
- Более легкое понимание структуры проекта
Компоненты контейнера
Характеристики:
- Обеспокоен тем, как обрабатываются данные
- Обычно не имеют языка разметки в качестве прямого потомка (они обычно вкладывают другие компоненты внутрь с использованием разделов-оболочек или других семантических тегов)
- Часто имеют состояние (хранение и обработка состояния React & Redux/Context/MobX)
- Предоставляйте данные и поведение вложенным компонентам (контейнеру или презентеру) через реквизиты (данные и обратные вызовы)
Примеры:
- Представления (Страницы), которые будут хранить данные более высокого уровня и распределять их по компонентам страницы: Домашняя страница, Страница входа, Страница регистрации, страница сообщений в блоге и т. д.
CommentsSection
, будет компонентом, который извлекает и сохраняет комментарии к сообщению или статье, а также распределяет содержимое по общему компоненту списка или сопоставляет эти данные через список компонентовComment
PopularTopics
, который представляет собой синхронизированный/в режиме реального времени список популярных тем в отношении платформы социальных сетей, который постоянно извлекает данные в режиме реального времени для предоставления полезной информации о самых популярных/актуальных темах на платформе.
Компоненты представления
Характеристики:
- Беспокоится о том, как все выглядит
- Зависит исключительно от переданных данных и обратных вызовов (через реквизиты)
- В основном они содержат состояние, связанное с пользовательским интерфейсом (isDropdownOpen, isPopoverOpen и т. д.)
- Не беспокойтесь о том, как данные загружаются или монтируются
Примеры:
Navbar
, общий компонент панели навигации, который имеет некоторые предопределенные данные (ссылки) или может иметь некоторые вложенные динамические ссылки (возможно, динамические релевантные категории), которые могут быть инкапсулированы в компоненте-контейнере.
- «Боковая панель», аналогичная ранее упомянутому компоненту «Навигатор».
Список
, общий компонент, который принимает массив в качестве реквизита и отображает список; его единственная проблема заключается в соответствующем отображении данных (семантика + стили)
Простой и подходящий пример того, когда и как разделить компонент в соответствии с шаблоном Container/Presenter, можно найти здесь .
Вам также могут быть полезны эти статьи:
Эта статья была первоначально опубликована [здесь] (https://medium.com/web-dev-freelancing/react-design-patterns-container-presenter-pattern-e7f2650442d7)
Оригинал