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

Исходный компонент

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

Нарушение принципа единоличной ответственности

Таким образом, приведенный выше компонент делает то, что мы хотим, но он не является гибким или многоразовым, поскольку не соответствует принципу единой ответственности. Что вы спрашиваете?

Принцип единой ответственности (SRP) - один из пяти так называемых принципов SOLID, разработанных и продвигаемых Робертом Мартином, чтобы помочь разработчикам создавать гибкий и поддерживаемый код. Короче говоря, SRP гласит, что данный модуль или класс должен нести ответственность за один элемент функциональности программы и, таким образом, иметь только одну причину для изменения . - Северин Перес

Если вы хотите узнать больше о принципе единой ответственности, ознакомьтесь со статьей Северина Переса (ссылка на которую приведена в цитате выше и в ссылках в конце этой статьи).

Глядя на наш исходный компонент, мы видим, что он отвечает за несколько различных логических операций:

  1. Отрисовка элемента упаковки с заголовком.
  2. Управление состоянием тумблера.
  3. Отображение div с button и условным текстом.

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

Рефакторинг # 1

Давайте сделаем первый проход при рефакторинге и попробуем разделить наш исходный компонент, чтобы у него был родительский компонент, который будет отвечать за управление состоянием, а затем отобразит функциональный компонент, который будет отвечать за кнопку и условный текст, тем самым отделяя проблему 3 от 1 и 2.

Наш функциональный компонент ToggleWindow обращается к проблеме 3 и принимает свойства функции toggle и значения isToggled, а также отображает необходимые элементы с предоставленной информацией. Toggler теперь отвечает только за вопросы 1 и 2.

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

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

Хотя сначала ...

Что такое реквизит для рендеринга?

Согласно документации React:

Термин рендеринг опоры относится к методике совместного использования кода между компонентами React с использованием опоры, значение которой является функцией.

Компонент с опорой рендеринга принимает функцию, которая возвращает элемент React, и вызывает его вместо реализации собственной логики рендеринга.

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

Рефакторинг # 2

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

Если вы немного запутались, не волнуйтесь, код лучше объясняет это. Я создал пример ниже, где у меня есть два отдельных компонента, которые имеют разные стили и спецификации содержимого как для родительского, так и для дочернего элемента. Оба они получают «добавленный» Toggler логический компонент, но не нуждаются в его переопределении. Взглянем:

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

Логика переключения была повторно использована таким же образом для каждой из двух различных реализаций. Я создал 2 варианта использования функциональных / презентационных компонентов, которые используют Toggler, но повторно используют Toggler в обоих случаях, не переопределяя или изменяя его.

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

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

Ресурсы:



Свойства рендеринга - React
Термин« свойство рендеринга
относится к методике совместного использования кода между компонентами React с использованием свойства, значение которого равно… reactjs.org »