Skip to main content

Композиція компонентів

Що таке "композиція компонентів"

Композиція компонентів (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 декларативним, передбачуваним і гнучким.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.