Що таке «presentational component»?
Коротке визначення
Presentational component (презентаційний компонент) - це компонент, який відповідає лише за зовнішній вигляд (UI) і не містить бізнес-логіки чи стану застосунку.
Іншими словами:
Це «дурний» компонент, який просто приймає дані через
propsі відображає їх у вигляді JSX.
Відмінність від контейнерного компонента
| Характеристика | Presentational (UI) | Container (Логіка) |
|---|---|---|
| Основне завдання | Відображення даних | Керування даними |
| Де зберігаються дані | У props | У state, контексті або сторі |
| Стан (state) | Майже ніколи | Зазвичай є |
| Логіка (fetch, фільтри, обробники) | Немає | Є |
| Зв'язок із сервером | Немає | Є |
| Можливість повторного використання | Дуже висока | Обмежена контекстом |
| Приклад | UserCard, Button, Header | UserContainer, ProductsContainer |
Приклад 1. Простий презентаційний компонент
function UserCard({ name, email }) {
return (
<div className="user-card">
<h3>{name}</h3>
<p>{email}</p>
</div>
);
}Особливості:
- Немає стану (useState).
- Немає сайд-ефектів (useEffect).
- Лише відображення даних.
- Отримує все через props.
Використання:
<UserCard name="Tim" email="tim@example.com" />Приклад 2. Розділення контейнера та презентаційного компонента
function UserContainer() {
const [user, setUser] = useState(null);
useEffect(() => {
fetch("/api/user")
.then(res => res.json())
.then(setUser);
}, []);
if (!user) return <p>Loading...</p>;
return <UserCard name={user.name} email={user.email} />;
}Тут:
- UserContainer -> логіка (fetch, state);
- UserCard -> відображення (розмітка, стилі).
Такий розподіл робить код чистим і придатним для повторного використання.
Приклад 3. Презентаційний компонент із children
function Card({ title, children }) {
return (
<div className="card">
<h2>{title}</h2>
<div>{children}</div>
</div>
);
}Використання:
<Card title="Profile">
<UserCard name="Anya" email="anya@example.com" />
</Card>Компонент Card не знає, що саме всередині, він просто відповідає за структуру та стиль.
Приклад 4. Презентаційний компонент як UI-бібліотека
Більшість UI-компонентів (наприклад, із shadcn/ui, Material UI, Chakra UI) - це presentational components.
Приклади:
<Button variant="primary">Submit</Button>
<Alert type="error">Error!</Alert>
<Modal isOpen>Content</Modal>Усі вони не керують станом даних, вони просто відображають те, що їм передали.
Приклад 5. Мінімум логіки всередині
Іноді допускається мінімальна UI-логіка, наприклад:
- підсвічування вибраного елемента;
- перемикання класів;
- локальні ефекти UI (hover, active, collapse тощо).
function ToggleButton({ active, label }) {
return (
<button className={active ? "btn-active" : "btn"}>
{label}
</button>
);
}Це все ще «presentational» - жодного стану, лише реакція на пропси.
Чому цей підхід важливий
Розділення відповідальності: логіка окремо, відображення окремо.
Можливість повторного використання: той самий UI-компонент можна використовувати в різних місцях.
Легке тестування: можна просто перевірити, що він рендерить правильний JSX для даних.
Чистий код: презентаційні компоненти не «обтяжують» логіку застосунку.
Підсумок
| Що це | Компонент, який лише відображає дані |
|---|---|
| Де зберігає дані | У props |
| Чи має стан | Ні (майже ніколи) |
| Де використовується | Усередині контейнерних або інших UI-компонентів |
| Що містить | JSX, стилі, children |
| Головна мета | Відокремити візуальну частину від логічної |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.