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

Подход React к созданию приложений побуждает разработчиков создавать повторно используемые компоненты и модульные пользовательские интерфейсы.

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

Об этом было вложено много размышлений, и сообщество разработало Контейнер и Компоненты представления, которые являются способом отделения логики приложения от представления. Компоненты контейнера заботятся о том, как работает приложение, а компоненты представления - о том, как оно выглядит. Последний должен быть простым, общим и многоразовым. Если вы не знакомы с этой концепцией (также называемой интеллектуальными и глупыми компонентами), я предлагаю вам прочитать Статью Дэна Абрамова на эту тему.

Давай запачкаем руки

… И увидеть весь процесс разработки реального Компонента.

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

<a class='facebook-button' href='/auth/facebook'>Login with FB</a>

Затем нам понадобилась следующая кнопка, на этот раз красная для входа в Google.

<a class='google-button' href='/auth/google'>Login with G+</a>

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

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

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

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

На этом этапе наш Компонент будет работать, как ожидалось. Для отображения кнопки нужен только определенный тип и метка.

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

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

Обратите внимание, что каждый раз, когда render () вызывается в <SocialMediaLogin />, ему потребуется необходимое изображение. Если по какой-либо причине Компонент повторно визуализируется несколько раз, изображение будет требоваться снова и снова. Поскольку мы создаем здесь презентационный компонент, мы должны быть осторожны, чтобы не оставлять логику на усмотрение <SocialMediaLogin />. Таким образом, вместо того, чтобы позволить Компоненту решать, какой логотип следует напечатать, Контейнер, который выполняет вызов, должен взять на себя эту ответственность.

Окончательный рефакторинг

Благодаря этому мы можем вызывать наш <SocialMediaLogin /> Компонент, не опасаясь неожиданных результатов. На данный момент <SocialMediaLogin/> не имеет состояния, которое нужно поддерживать, и также не использует какие-либо методы жизненного цикла React. Это идеальная ситуация для преобразования его в функциональный компонент.

Несмотря на то, что изменения не выглядят такими уж масштабными, функциональные компоненты - прекрасная возможность помочь React оптимизировать наш код. Они приходят без управления состоянием и жизненного цикла React. В Примечаниях к выпуску React 0.14 Бен Альперт оптимистично надеется, что в будущих выпусках будут избегать ненужных проверок и выделения памяти. Кроме того, функциональные компоненты заставляют вас думать о компонентах в их чистом виде - как о настоящих презентационных компонентах.

Вывод

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

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