Comments 9
Т.е. вместо сложной логики в одном компоненте их сделали несколько конкретных и завернули в общий контекст от компонента предка? И их нужно явно указывать?
Да, по сути так. А ты потом просто выбираешь, какие части этого компонента использовать в разных случаях.
Имеешь ввиду, обязательно ли писать вот так
<Accordion.Item>
? Нет, не обязательно, во первых ты можешь сделать деструктуризацию:const { Item } = Accordion
На самом деле можно даже не делать
Item
как свойствоAccordion
Вот как раз такая явно указанная связь в именовании и смущает, так как по факту Accordion и Accordion.Item связаны лишь контекстом, а его провайдить могут и другие компоненты, а не один лишь Accordion. Ну и пример на мой взгляд неудачный, т.к. Accordion.Item явно попадают в children и Accordion может с ними делать что угодно вообще без контекста.
а его провайдить могут и другие компоненты
Не могут. Откуда им взять этот контекст? Он вшит куда-нибудь в модуль Accordion
и снаружи недоступен.
т.к. Accordion.Item явно попадают в children и Accordion может с ними делать что угодно вообще без контекста
Не могут. Ваши возможности с обработкой children лимитируются тем, что Item
-ы должны в них присутствовать "как есть". Вернуть туда компонент, который уже сам вернёт Item
-ы внутри себя не получится. Возможности React.Children.map
весьма ограничены.
В целом, когда сторонние библиотеки, вместо слотов c использованием контекста, используют React.Children.map
ужасно бесят. По сути они очень сильно лимитируют разработчика в том, как ему организовать код. Он обязан порешать всё в одном и том же компоненте, даже если это нарушит все мыслимые принципы clean code. Не делайте так, пожалуйста :) Используйте контексты.
Довольно часто требуется ещё и плоская структура для children. Это ещё больше раздражает.
Согласен что cloneElement решение так себе, но проблемы экспортировать контекст наружу вроде нету. Кроме того непосредственных чилдов можно завернуть в рендер функцию с доп параметрами. Само решение Compound components хорошо, но упомянуть альтернативные решения, и чем они хуже/лучше предложенного было бы полезно.
но проблемы экспортировать контекст наружу вроде нету
Что вы хотели этим сказать? То что можно зайти в код компоненты и сделать экспорт. А потом этим где-нибудь ещё воспользоваться? Эмм… А зачем? Как это пройдёт code review. Наверное я вас не понял.
можно завернуть в рендер функцию с доп параметрами
Рендер функции и компоненты это отнюдь не одно и то же. Удачи:
- воспользоваться в ней хуками
- хоками
- сделать иерархию компонент
- и т.д.
и чем они хуже/лучше предложенного было бы полезно.
По сути эти единственное нормальное решение если вам нужна гибкость на уровне children
.
Спасибо, тоже использую этот паттерн. Удобно и красиво.
Тоже часто использую такой подход. В контекст обычно кладу экземпляр класса, который сочетает логику и мобх-стор (или несколько таких).
Вообще говоря, Реакт-приложение в целом - это один большой Compound. Идея о том, что внутри одного Compound могут быть другие Compound, естественна.
Улучшаем дизайн React приложения с помощью Compound components