Итак, вы используете компонентный фреймворк, такой как React JS, Vue JS или последнюю версию Angular? Несколько лет назад React популяризировал идею компонентов как способ повторного использования кода и более эффективного создания веб-приложений.

«Теоретически это здорово, но по моему опыту эти причудливые« многоразовые »вещи никогда не используются повторно», - сказал мой скептически настроенный 43-летний коллега, когда я познакомил команду с VueJS.

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

Как вы определяете объем компонента? Как вы решаете, что должно быть включено в один компонент, а что оставить для отдельного компонента?
Куда вы помещаете стили?
В какой момент лучше иметь 2 отдельных, но больше простые компоненты, а не один общий компонент, который слишком сложен?

TL, DR, 3 основных правила многократно используемых компонентов:
- создавайте как можно меньше компонентов
- компоненты должны быть «достаточно общими» и, в идеале, должны органически извлекаться со страниц приложения по мере создания. их
- два простых компонента лучше, чем один общий сложный компонент

Примечание: в большинстве примеров в этой статье используется React, но общие идеи актуальны для любой инфраструктуры на основе JS-компонентов, такой как Vue или Angular.

Сделайте как можно меньше компонентов

Проблема: слишком много слоев в дереве компонентов.

В своем первом приложении React я совершил ошибку, разделив простую функциональность на слишком много компонентов. Я почти сделал компонент для каждого слоя div… Это означает, что много времени было потрачено впустую на передачу свойств вниз по дереву компонентов. Это утомительно, и если вы забудете одну опору в одном слое, приложение сломается. Всякий раз, когда вы хотите изменить сигнатуру компонента в цепочке или при изменении типа опоры, вам необходимо внести изменения на каждом уровне.
Это отрицательно сказывается на скорости разработки, но также отрицательно влияет на производительность, когда вы разделяете свое приложение на большее количество компонентов, чем это абсолютно необходимо: больше вызовов функций, больше файлов для разрешения и объединения (см. Стоимость малых модулей).

Решение: разделяйте страницу или блок на несколько компонентов только в случае крайней необходимости.

Просмотр кода React других людей на GitHub помог мне понять, что я делаю неправильно.

Пример: меню со списком ссылок.

Раньше я спонтанно создавал два компонента: компонент MenuGroup и компонент MenuItem.

Это сработает. Но, если menuLinks не являются динамическими, лучше вообще не создавать компонент MenuItem и описывать все меню в одном компоненте Menu с жестко закодированными данными:

Чтобы уменьшить количество компонентов, избегайте создания компонентов, которые только добавляют стили. Вместо компонента BlueButton лучше просто использовать HTML-тег «button» и добавить к нему класс «.blue».

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

Компоненты должны быть «достаточно универсальными».

Проблема: простая или универсальная?

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

Решение: используйте только внешние библиотеки компонентов, если это действительно необходимо.

Так много о повторном использовании кода или изобретении велосипеда? Для меня цель библиотек, таких как React-bootstrap, не в том, чтобы использовать их в качестве дополнения к вашему проекту. Я просто смотрю на их код, чтобы увидеть, как они решили какую-то проблему, с которой я столкнулся при создании собственного пользовательского компонента. Например, как создать компонент с бесконечной прокруткой или перетаскивание для загрузки файла. Я скопирую основную идею, которая часто представляет собой не более 10 строк кода, а затем построю на ее основе свой собственный компонент, удалив много лишнего и ненужного усложнения.

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

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

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

Используйте слоты вместо реквизита

По возможности используйте прорези вместо реквизита. В Vue JS это означает использование именованных слотов. В React, где у вас есть только слот по умолчанию, рекомендуется использовать компоненты более высокого порядка (то есть декораторы) для добавления функциональности вместо свойств.

Пример: вместо того, чтобы получать заголовок как опору, лучше поместить его в слот:

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

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

Если компонент предполагается использовать в разных контекстах, помещайте в реквизиты только те данные, которые унаследованы от прямого родительского компонента. По возможности получайте данные напрямую из глобального состояния, используя метод подключения «react-redux». Таким образом, если некоторые данные нужны только в этом компоненте, вам не нужно передавать их по всему дереву компонентов.

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

Два простых компонента лучше, чем один общий сложный компонент

Проблема: зачастую проще скопировать, чем взломать, чем использовать повторно.

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

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

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

Повторное использование кода - это хорошо, но важнее скорость разработки. Можно начать с дублирования существующего компонента. Эти два компонента иногда можно объединить позже.

Вот простой рабочий процесс разработки, который подчеркивает 3 правила, описанные выше:
1) Начните с создания первой страницы в одном компоненте
2) Создайте вторую страницу также в одном компоненте
3 ) Если и только если между двумя страницами есть общие компоненты, сделайте их общими и извлеките в отдельную папку.

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

Если вы нашли эту статью полезной, обязательно ознакомьтесь с React Without Webpack: Faster Developer Workflow, где объясняется, как избежать этапа сборки во время разработки.