Skip to main content

Що таке "container component"?

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

Container component (контейнерний компонент) - це компонент, який:

відповідає за логіку, дані та стан, але не відповідає за зовнішній вигляд (розмітку).

Зазвичай він:

  • отримує дані (з API, контексту, стора тощо);
  • керує станом (useState, useEffect);
  • передає ці дані у презентаційний (UI) компонент через props.

Ідея розділення

React-компоненти можна умовно розділити на два типи:

ТипЩо робитьМістить
Presentational (UI)Відповідає за відображення (розмітка, стилі)JSX
Container (розумний)Відповідає за логіку, дані, станхуки, API, обробники

Приклад 1. Базовий приклад

Презентаційний компонент:

javascript
function UserCard({ name, email }) { return ( <div className="user-card"> <h3>{name}</h3> <p>{email}</p> </div> ); }

Цей компонент:

  • просто малює дані;
  • не знає, звідки вони взялися.

Контейнерний компонент:

javascript
function UserContainer() { const [user, setUser] = useState(null); useEffect(() => { fetch("/api/user") .then(res => res.json()) .then(data => setUser(data)); }, []); if (!user) return <p>Завантаження...</p>; return <UserCard name={user.name} email={user.email} />; }

Цей компонент:

  • керує завантаженням даних;
  • зберігає стан;
  • передає результат у UserCard.

Приклад 2. Чисте розділення відповідальності

javascript
App UserContainer (логіка) UserCard (відображення)

UserContainer вирішує, що показувати, UserCard вирішує, як це виглядає.


Приклад 3. Контейнер може керувати кількома UI-компонентами

javascript
function ProductsContainer() { const [products, setProducts] = useState([]); const [filter, setFilter] = useState(""); useEffect(() => { fetch("/api/products") .then(res => res.json()) .then(data => setProducts(data)); }, []); const filtered = products.filter(p => p.name.includes(filter)); return ( <> <SearchBar value={filter} onChange={setFilter} /> <ProductList items={filtered} /> </> ); }

Тут:

  • Контейнер керує даними і фільтрацією;
  • SearchBar і ProductList просто відображають UI.

Переваги підходу "Container + Presentational"

Розділення обов'язків - логіка окремо, UI окремо Повторне використання - UserCard можна використовувати в різних місцях Тестованість - можна тестувати UI і логіку окремо Простота підтримки - зміни в логіці не ламають розмітку Покращена читабельність коду


Приклад 4. Універсальний шаблон

javascript
// Container function DataContainer({ render }) { const [data, setData] = useState([]); useEffect(() => { fetch("/api/items") .then(r => r.json()) .then(setData); }, []); return render(data); } // Використання <DataContainer render={(items) => <ItemList items={items} />} />

Тут використовується render prop, але сенс той самий - контейнер займається даними, а дочірній компонент - відображенням.


Коли використовувати контейнерні компоненти

Використовуй, якщо:

  • компонент повинен завантажувати дані (API, GraphQL, Firebase);
  • потрібно зберігати стан (useState, useReducer);
  • компонент керує логікою взаємодії (наприклад, фільтри, сортування, форма);
  • ти хочеш відокремити візуальний шар від логічного.

Коли не потрібно

Не створюй контейнер, якщо:

  • компонент просто відображає UI;
  • у ньому немає логіки або стану;
  • дані приходять вже готовими через props.

Підсумок

Тип компонентаОсновне завданняПриклад
ContainerЛогіка, стан, запити, обробникиUserContainer, ProductsContainer
Presentational (UI)Розмітка і відображення данихUserCard, ProductList

Головна думка:

Container component - це "розумний" компонент, який керує логікою і даними, а візуальну частину делегує "дурним" (презентаційним) компонентам.

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

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

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