Комментарии 13
в приведенных фрейворках слоты появились потому, что там для рендера везде используются шаблоны со своим неповторимым синтаксисом, а в реакте всё является функциями и render props — самый естественный подход
Согласен, но в renderProps мне не хватает семантики, чтобы вёрстка говорила сама за себя. И тут, возможно, дело вкуса. Мне, чем сложнее компоненты отрисовываются в renderProps, тем сложнее читать:
<Dialog>
<CloseSlot>
<button>close me</button>
</CloseSlot>
...
</Dialog>
И
<Dialog
renderCloseButton={() => <button>close me</button>}
>
...
</Dialog>
1) Так зачем передавать функцию?
<Dialog close={<button>close</button>} />
2) Как обеспечить обязательность слотов на уровне typescript?
1) Согласен
2) Под обязательностью вы имеете в виду как сделать использование слота обязательным? Чтобы пользователь компонента не мог игнорировать слот и был обязан что-то в него положить? К сожалению, насколько я знаю TypeScript и типизацию JSX, это нельзя выразить типами.
Справедливые замечания, спасибо!
Я не часто пишу на react, но вроде же можно было описать props компонента при помощи интерфейса и ts даже проверял такие места. Почему бы и не указать в этом же интерфейсе функцию как prop?
UPD. Действительно, можно.
https://codesandbox.io/s/focused-field-3oq5w?file=/src/App.tsx
с поддержкой параметризации слотов.
Получить доступ к дефолтному содержимому слота тоже можно? Что-то типа:
<MySlot>
{params => (<div>Param is {params.myParam} and {params.defaultSlotContent}</div>)}
</MySlot>
P.S.: о том, какими должны быть слоты, неплохо рассказал Константин Лебедев в этой статье.
defaultSlotContent
нету, но можно легко добавить. Пожалуй, так и сделаю!
За ссылку на статью спасибо! Идеи похожи, и там есть преимущества (не надо руками передавать children
) и недостатки (привязка по строковому имени ломает навигацию в IDE).
Но представленный там способ требует намного большей интеграции в проект – компоненты должны создаваться через фабрику. Не хотелось бы настолько завязываться на утилитарную библиотеку.
Интересный подход)
Ребята из БЭМа тоже решали ее проблему, можно тут почитать https://ru.bem.info/technologies/bem-react/ В основе — DI.
Да писали уже про это тут https://habr.com/ru/post/475170/
Всякий раз когда у меня появляется желание написать свою версию слотов для React я говорю себе — не делай этого!
А если заменить "фатальный недостаток" на "фича" то и проблемы решатся сами собой.
<Select items={[]} />
<Select items={[]} slotItem={<CustomItem />} />
Компонент реализует нужную вёрстку и логику по умолчанию, а если нужно заменить какую-то часть, то создаём для этого слот и передаём в него произвольный компонент. Все слоты считаются необязательными параметрами и без них компонент должен правильно работать.
React: слоты как у сына маминой подруги