В Preact children представляют собой способ передачи
вложенного содержимого компонентам. Это мощный инструмент, позволяющий
строить компоненты высокой переиспользуемости и создавать гибкие
пользовательские интерфейсы.
children — это специальное свойство
(props.children), которое автоматически содержит все
элементы, размещённые внутри тега компонента. Рассмотрим пример:
import { h } from 'preact';
function Card(props) {
return (
<div className="card">
{props.children}
</div>
);
}
// Использование
<Card>
<h2>Заголовок карточки</h2>
<p>Описание карточки</p>
</Card>
В этом примере компонент Card не знает заранее, какой
контент ему будет передан. Он просто выводит всё, что находится между
<Card> и </Card>, через
props.children.
Особенности children в Preact:
children могут быть любыми: элементами Preact,
строками, числами или массивами элементов.props.children
существует и равен undefined.Для удобства часто используют деструктуризацию:
function Card({ children }) {
return <div className="card">{children}</div>;
}
Если компонент получает несколько дочерних элементов,
children обычно представляет собой массив:
<Card>
<p>Первый абзац</p>
<p>Второй абзац</p>
</Card>
В props.children будет массив из двух элементов
<p>.
children можно фильтровать и модифицировать перед
рендерингом:
function Card({ children }) {
const filteredChildren = Array.isArray(children)
? children.filter(child => child.type !== 'p')
: children;
return <div className="card">{filteredChildren}</div>;
}
Такой подход позволяет создавать компоненты с логикой обработки вложенного контента.
В Preact нет встроенной концепции слотов, как в Vue или Web Components, но можно реализовать похожий паттерн через именованные пропсы.
Пример реализации «слотов»:
function Modal({ header, body, footer }) {
return (
<div className="modal">
<div className="modal-header">{header}</div>
<div className="modal-body">{body}</div>
<div className="modal-footer">{footer}</div>
</div>
);
}
// Использование
<Modal
header={<h2>Заголовок модального окна</h2>}
body={<p>Основное содержимое</p>}
footer={<button>Закрыть</button>}
/>
Такой подход позволяет гибко управлять содержимым каждой части
компонента, создавая аналоги слотов с именами header,
body, footer.
Можно комбинировать children и именованные «слоты» для
более сложных сценариев:
function Tabs({ children }) {
return (
<div className="tabs">
{Array.isArray(children) ? children.map((tab, index) => (
<div key={index} className="tab">{tab}</div>
)) : <div className="tab">{children}</div>}
</div>
);
}
// Использование
<Tabs>
<div>Вкладка 1</div>
<div>Вкладка 2</div>
</Tabs>
Такой подход позволяет динамически создавать интерфейс из множества
элементов, передаваемых через children.
Array.isArray или Children.toArray (из
Preact/compat при необходимости).children для всех вложенных элементов,
либо именованные пропсы для ключевых зон.Использование children и паттерна слотов обеспечивает
гибкость архитектуры Preact-приложений и позволяет строить
масштабируемые и легко поддерживаемые интерфейсы.