Skip to main content

SRP в React-компонентах

Що таке SRP (у загальному вигляді)

Single Responsibility Principle - принцип єдиної відповідальності.

Формулювання (за Робертом Мартіном, автором SOLID): "У модуля повинна бути одна і тільки одна причина для зміни."

У React цей "модуль" - компонент. Якщо компонент робить занадто багато, то:

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

SRP у React: просте визначення

React-компонент повинен робити тільки одну річ - і робити її добре.

Тобто:

  • Один компонент = одна відповідальність.
  • Якщо компонент керує і логікою, і зовнішнім виглядом, і даними, і API - він порушує SRP.

Приклад порушення SRP (поганий код)

javascript
function UserProfile() { const [user, setUser] = useState(null); useEffect(() => { fetch('/api/user') .then(res => res.json()) .then(setUser); }, []); const handleDelete = async () => { await fetch(`/api/user/${user.id}`, { method: 'DELETE' }); setUser(null); }; if (!user) return <div>Loading...</div>; return ( <div> <h1>{user.name}</h1> <button onClick={handleDelete}>Видалити користувача</button> </div> ); }

Проблеми:

  • Компонент завантажує дані (data fetching),
  • Відображає UI,
  • Містить бізнес-логіку (видалення),
  • Керує станом.

-> Занадто багато відповідальності в одному місці. -> Важко перевикористовувати, тестувати, підтримувати.


Приклад з SRP (правильний підхід)

Розділимо обов'язки:

1. Компонент відповідає за дані:

javascript
function useUser() { const [user, setUser] = useState(null); useEffect(() => { fetch('/api/user').then(res => res.json()).then(setUser); }, []); const deleteUser = async () => { await fetch(`/api/user/${user.id}`, { method: 'DELETE' }); setUser(null); }; return { user, deleteUser }; }

2. Компонент відображає дані (UI):

javascript
function UserProfileView({ user, onDelete }) { if (!user) return <div>Loading...</div>; return ( <div> <h1>{user.name}</h1> <button onClick={onDelete}>Видалити користувача</button> </div> ); }

3. Компонент-композиція (контейнер):

javascript
function UserProfile() { const { user, deleteUser } = useUser(); return <UserProfileView user={user} onDelete={deleteUser} />; }

Тепер:

  • useUser - відповідає за дані і бізнес-логіку;
  • UserProfileView - відповідає тільки за UI;
  • UserProfile - збирає їх разом.

Переваги SRP у React

ПеревагаЩо дає
ЗрозумілістьКожен компонент робить щось одне і очевидне
ПеревикористовуваністьUI-компонент можна використовувати з іншими даними
ТестованістьМожна окремо тестувати UI і логіку
ПідтримуваністьЗміна логіки не ламає розмітку
ПродуктивністьПростіше оптимізувати окремі частини
РозширюваністьМожна додавати нові функції без правок старих компонентів

Типові категорії відповідальності в React

КатегоріяПриклади компонентів
Презентаційні (UI)кнопки, картки, форми, списки, layout
Контейнерні (логіка)завантаження даних, виклики API, обробка подій
Композиційнізбирають UI-компоненти разом
Хуки / Логічні блокимістять бізнес-логіку без UI (useAuth, useCart, useUser)

Приклад архітектури за SRP

javascript
/components ├── ui/ │ ├── Button.tsxUI-компонент │ ├── Card.tsxUI-компонент │ └── UserProfileView.tsx← Відображення ├── containers/ │ └── UserProfile.tsx ← Контейнер /hooks └── useUser.ts ← Логіка даних

-> Кожен рівень робить тільки свою справу, React-компоненти стають як "чисті функції інтерфейсу".


Коли SRP порушується найчастіше

Типові ситуації:

  1. Компонент завантажує дані і одразу їх рендерить;
  2. UI-компонент зберігає локальний state, не пов'язаний з відображенням;
  3. Один компонент керує і layout'ом, і логікою;
  4. Надлишкові useEffect всередині UI-компонентів.

Підсумок

Що означає SRPУ React це означає
"Одна відповідальність"Компонент вирішує одну задачу
Легко тестуватиТому що робить щось одне
Легко розширюватиЗміна логіки не ламає UI
Архітектурно чистоUI, логіка і дані - окремо
ПрикладuseUser (логіка) + UserProfileView (UI) + UserProfile (композиція)

Простими словами:

Компонент React повинен бути як чистий інструмент: одна мета, одна поведінка, одне місце, де щось може зламатися.

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

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

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