Ваш React-додаток далекий від досконалості — ось чому.

З моменту свого першого публічного релізу в травні 2013 року, React запропонував інструменти для створення веб-застосунків у більш модульний спосіб. Однак ця відома бібліотека майже не дає вказівок щодо того, як правильно структурувати код, залишаючи розробникам велику гнучкість — як на користь, так і на шкоду.

Почнемо з нескромного запитання (вибачте за прямоту): чи ваші React-компоненти виглядають приблизно ось так?

const YourComponent = ({ props1, ..., props7 {  
 const { state1, setState1State<...>(...)  
 const { state2, setState2...)  
 const { state3, setState<...>(...)  
 // Ще більше стекових станів...  
 // ...  

 useEffect(() => {  
 // Приблизно двадцять (або більше) рядків, які відповідають за   
 // отримання та обробку даних для JSX  
 // сек [/* Довгий список змінних для спостереження. */])  

 // Інструкції для обробки даних та взаємодії з користувачем.  
 // ...  
 // Можливо, ще один useEffect() для ще більшого хаосу?  
 // ...  
 // На якому рядку ми зараз? Можливо, вже на рядку 105?  
 // ...  
 // Хелпери для створення JSX.  
 // ...  
 // Рядок 145 :(  
 // ...  
 return (  
 \  
 <...  
 (...)   
 Тридцять (або більше) рядків JSX...  
 (...)  
 ...>

Якщо так, давайте подумаємо, як ми можемо це покращити...

Я спробую вас переконати. Це коштуватиме трохи вашого часу й уваги, але (сподіваюся) заощадить вам і вашим колегам години, витрачені на заплутане налагодження коду, який виконує занадто багато завдань одночасно.

Ми можемо створити схему, щоб відобразити такий React-компонент.

![image](https://miro.medium.com/v2/resize:fit:1244/1*fVEF8IPLaGbYz4mGV9el1A.

pic

Як може виглядати ваш React-компонент...

Як бачите, наш React-компонент виконує щонайменше п’ять різних завдань:

  1. Управління React станами (states)
  2. Обробка дій користувача (user actions)
  3. Отримання даних через API, обробка помилок і керування етапами завантаження
  4. Трансформація та мапінг даних з різних джерел
  5. Визначення інтерфейсу користувача (UI) і DOM за допомогою JSX

Дуже багато, чи не так? Крім проблем із читабельністю (часто важко зрозуміти, що відбувається), така логіка складна для тестування і розширення. Більше того, застосунки, які залежать від подібних компонентів, часто втрачають консистентність у потоках даних. Інформація розкидана по всьому застосунку, що лише посилює плутанину.

Давайте спробуємо це виправити за допомогою розділення обов’язків (separation of concerns). Як це може виглядати?

pic

Розділення обов’язків робить ваш React-застосунок читабельним, тестованим і підтримуваним. Ваші колеги будуть вам вдячні ❤️.

Давайте розберемося в обов’язках (responsibilities) сутностей, представлених у схемі вище. Зліва направо:

Клієнти (Clients)

  • Клієнти відповідають за взаємодію з зовнішніми джерелами даних (external data sources), зазвичай через API.
  • Вони надають типізовані структури (typed structures), які контролери (controllers) можуть безпосередньо обробляти.
  • Клієнти відокремлені від життєвого циклу React (React lifecycle), тобто не залежать від React-компонентів. Це прості класи або функції, які містять інформацію про API.
  • Вони обробляють помилки API та повторно викидають ті помилки, які може обробити застосунок (зазвичай через Error Fallback).

Станові контролери (Stateful Controllers)

  • Станові контролери відповідають за управління станами React (React states).
  • Вони надають інтерфейси даних (data interfaces) для компонентів представлення (View Components), і ці дані безпосередньо використовуються в JSX, де вони впроваджені. Цей механізм можна назвати гідратацією даних (data hydration).

  • Станові контролери (Stateful Controllers) також надають зворотні функції (callback functions), щоб дозволити користувачам змінювати стан і викликати API.

  • Станові контролери можна створити, поєднуючи React-хуки (React hooks) та контексти React (React contexts). React-хуки дозволяють легко підключити контролери до компонентів представлення, а контексти React роблять стани глобальними. Таким чином, ви можете легко під’єднати будь-який компонент представлення до будь-якого станово контролера, забезпечуючи спільне використання стану.

  • Станові контролери не працюють із жодним рядком JSX, що спрощує тестування, оскільки вихідними даними є набір структурованих даних і зворотних функцій.

Станові (і безстанні) контролери заслуговують на окрему статтю. Будь ласка, дайте знати в коментарях, якщо вам цікаво заглибитися в ці концепції.

Мапери і трансформери даних (Data Mappers and Transformers)

  • У деяких випадках дані, отримані через API (або дані, що відправляються в API), потребують складних трансформацій. Для покращення тестованості ці операції можна винести у окремі модулі.
  • Мапери і трансформери даних відокремлені від життєвого циклу React (React lifecycle).

Компоненти представлення (View Components)

  • Компоненти представлення — це простi компоненти, які підключаються до контролерів і впроваджують дані в JSX.
  • Вони не обробляють, не трансформують і не керують даними. Замість цього, ці завдання делегуються контролерам.
  • Вони більше не використовують props, тому що отримують дані від контролерів через хуки. Це спрощує потік даних і забезпечує узгодженість.
  • Вони не керують станами.
  • Їх легко тестувати за допомогою знімків (snapshots) або базових перевірок у Jest.

З таким підходом "передача пропсів через кілька рівнів" (prop drilling), "пекло зворотних викликів" (callback hell) та висока когнітивна складність (а іноді й Redux 🎉) стають лише спогадами.

Ось і все. Ця коротка стаття мала на меті надати вам швидкий огляд того, як покращити ваш React-застосунок. Якщо ви зацікавлені глибше зануритися в конкретні концепції з більш докладними прикладами, я буду радий написати більше статей на цю тему. Будь ласка, залишайте свої запити та відгуки в коментарях.

Дякуємо, що прочитали!

Level Up Coding

Дякуємо, що є частиною нашої спільноти! Перед тим як піти:

  • 👏 Підтримайте цю статтю лайком і підпишіться на автора 👉
  • 📰 Перегляньте більше контенту в публікації Level Up Coding
  • 💰 Безкоштовний курс із підготовки до технічних співбесід ⇒ Переглянути курс

🔔 Слідкуйте за нами: Twitter | LinkedIn | Розсилка

🚀👉 Приєднуйтесь до колективу талантів Level Up і знайдіть чудову роботу

Перекладено з: Your React App Isn’t Great — Here’s Why.

Leave a Reply

Your email address will not be published. Required fields are marked *