Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Композиція компонентів». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Композиція компонентів (component composition)** - це спосіб збирати інтерфейс із незалежних, переюзабельних блоків, комбінуючи їх один з одним, як конструктор LEGO. **Ключове:** один компонент може включати, обгортати або вбудовувати інші компоненти, формуючи складний UI, замість того щоб від них успадковуватися.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке "композиція компонентів" > **Композиція компонентів (component composition)** - це спосіб **збирати інтерфейс із незалежних, переюзабельних блоків**, комбінуючи їх один з одним як **конструктор LEGO**. Іншими словами: > Один компонент може **включати**, **обгортати** або **вбудовувати** інші компоненти, формуючи складний UI. --- ## Приклад композиції ### 1. Базовий компонент ```javascript function Card({ children }) { return <div className="card">{children}</div>; } ``` ### 2. Використання через композицію ```javascript <Card> <h2>Заголовок</h2> <p>Опис картки</p> </Card> ``` > Тут `Card` не знає, *що саме* всередині. > Він просто "контейнер", а контент вставляється через `children`. > Це і є **композиція** - об'єднання компонентів через включення один в одного. --- ## Композиція замість успадкування ### Успадкування (класичний ООП-підхід) Якби React був побудований на успадкуванні, довелося б робити так: ```javascript class SpecialButton extends Button { render() { return <button style={{ color: "red" }}>{this.props.label}</button>; } } ``` > Тобто "розширювати" наявний компонент. > Це **жорстко зв'язує** компоненти: якщо базовий зміниться, може зламатися нащадок. --- ### Композиція (React-підхід) ```javascript function Button({ children, ...props }) { return <button {...props}>{children}</button>; } function SpecialButton() { return <Button style={{ color: "red" }}>Натисни</Button>; } ``` > Ми **використовуємо компонент усередині іншого**, > замість того щоб від нього **успадковуватися**. > Це дає більше гнучкості і менше зв'язків. --- ## Чому React обрав композицію | Причина | Пояснення | |---|---| | Гнучкість | Можна комбінувати компоненти в будь-яких структурах | | Ізоляція | Кожен компонент незалежний, не знає деталей інших | | Переюзабельність | Один компонент можна вставляти в різні контексти | | Ясний інтерфейс | Компонент керує лише своїми `props` і `children` | | Менше зв'язків | Немає жорсткої ієрархії класів (на відміну від ООП) | | Композиція = декларативність | "Я описую, *що включено в що*", а не "який клас розширює який" | --- ## Типи композиції в React ### 1. Через `children` Найбазовіший спосіб: ```javascript <Layout> <Sidebar /> <Content /> </Layout> ``` → компонент `<Layout>` рендерить `props.children`. --- ### 2. Через пропси-компоненти Можна передавати конкретні "слоти": ```javascript function Dialog({ title, footer, children }) { return ( <div className="dialog"> <h2>{title}</h2> <div>{children}</div> <footer>{footer}</footer> </div> ); } <Dialog title="Видалити акаунт?" footer={<button>Так, видалити</button>} > <p>Цю дію не можна скасувати.</p> </Dialog> ``` > Такий спосіб часто називають **"slot pattern"** - > коли всередину компонента можна вставляти різні частини інтерфейсу. --- ### 3. Через Compound Components (складніший варіант композиції): ```javascript <Accordion> <Accordion.Item> <Accordion.Header>Питання</Accordion.Header> <Accordion.Panel>Відповідь</Accordion.Panel> </Accordion.Item> </Accordion> ``` > Тут уся логіка в `Accordion`, але розробник **сам композиційно будує UI**. --- ### 4. Через render-props (ще один спосіб композиції через функції): ```javascript <DataProvider render={(data) => <Chart data={data} />} /> ``` --- ## Чому композиція краща за успадкування | Критерій | Композиція | Успадкування | |---|---|---| | Розширення поведінки | Через вкладення і props | Через `extends` | | Гнучкість структури | Дуже висока | Жорстка ієрархія | | Ізоляція | Компоненти незалежні | Класи пов'язані | | Переюзабельність | Відмінна | Обмежена | | Ризик поломки | Мінімальний | Високий (при зміні базового класу) | | Підхід у React | Пріоритетний | Не використовується | --- ## Метафора - **Композиція** = LEGO: можна зібрати що завгодно з незалежних блоків. - **Успадкування** = ДНК: якщо змінити "батька" - ламаються всі "нащадки". --- ## Підсумок | Що | Опис | |---|---| | Композиція | Об'єднання компонентів шляхом включення їх один в одного | | Мета | Переюзабельність і гнучкість без жорстких зв'язків | | Приклад | `<Card><Header /><Body /></Card>` | | Перевага | Ізоляція, читабельність, масштабованість | | Успадкування | Занадто жорстке і не підходить під декларативну модель React | --- > **Головна думка:** > React-компоненти не успадковуються - вони **компонуються**. > > Замість "створити новий клас від старого" → ти "вставляєш компонент в інший". > Це і робить React декларативним, передбачуваним і гнучким.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.