Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Зачем это?
React основан на компонентом подходе. Когда создается компонент, предполагается, что его будут использовать по назначению. Если в проекте есть таблицы значит надо использовать <Table /> (к примеру), формы - значит <Form />. Естественно названия носят абстрактный характер, в каждом проекте они могут иметь разные названия, но суть их одна.
На практике нередко встречается такое, что разработчики, особенно новые, пытаются обойти некие правила использования, и за этим может уследить только TeamLead (или тот кто проводит ревью). И для того что бы облегчить эту работу, я расскажу о том какой паттерн можно для этого использовать, покажу какие модификации для этого следует внести и естественно все это подкреплю практическими примерами.
Меня зовут Дмитрий Чернов - старший инженер-программист в компании Nord Clan. И мы начинаем.
Pattern Compound Copmonents
Перед тем как начать, расскажу предысторию. У нас в проекте в определенный момент возникли проблемы с модальными окнами. А именно это не корректное использование этих окон. К каждому окну применялись кастомные стили, кнопки использовались как попало, горячие клавиши работали в зависимости от страницы использования (т.е. обработкой занималась ключевая страница на которой вызывалась модальная форма). Разработчиков было не много но даже двух, включая меня хватило что бы многое запоганить. Цель была создать что-то такое, что не позволит использовать компонент нет так как это задумывается по дизайну или тимлидом.
В поисках решения я наткнулся на интересный паттерн Copmonent Compound - это подход который связывает несколько компонентов путем общей сущности и состояния.
Для простоты можно привести примеры из html, основанные на этом подходе - тег <select> с его дочерним тегом <option>. Тег option не может использоваться без тега select. Они непосредственно связаны.
Из более приближенного к React примерам можно упомянуть Context - его составляющие Provider и Consumer, где второй не может использоваться без первого, основаны на том же принципе. Provider обязательно должен присутствовать и быть оберткой для использования Consumer.
<!-- HTML -->
<select>
<option>1 вариант<option/>
<option>2 вариант<option/>
<option>3 вариант<option/>
</select>
<!-- React -->
<React.Provider>
<React.Consumer>
<App />
</React.Consumer>
</React.Provider>
Чтобы глубже понять область применения, представьте себе использование такого подхода на примере компонента Table и Row, именно их можно чаще всего встретить при поиске описания паттерна в интернете. Мы можем использовать компонент <Row /> только внутри компонента <Table></Table>. Но использовать Table без Row нам ничто не запрещает. Более того мы можем использовать другие компоненты или элементы внутри Table.
Итог - данный подход меня устроил, но к сожалению проблему он решил частично.
В моем случае с модальными окнами, нужно было запретить разработчику прокидывать кастомные окна и использовать именно те которые будут удовлетворять требованиям дизайна.