Вступ в React, якого нам не вистачало

Alex Alex 15 жовтня
Вступ в React, якого нам не вистачало

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

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

Цей матеріал  написаний для тих, хто хоче знайти відповідь на наступні питання: «Чому React? Чому React працює саме так? З якою метою API React влаштовано так, як влаштовано? ».

Чому React?

Життя стає простіше в тому випадку, якщо компоненти не знають про обмін даними по мережі, про бізнес-логіку застосунку або про його стан. Такі компоненти, отримуючи одні і ті ж вхідні параметри, завжди формують одні і ті ж візуальні елементи.

Коли з'явилася бібліотека React - це на фундаментальному рівні змінило те, як працюють JavaScript-фреймворки і бібліотеки. У той час як інші подібні проєкти просували ідеї MVC, MVVM та інші подібні, в React був обраний інший підхід. А саме, тут рендеринг візуальної складової програми був ізольований від представлення моделі. Завдяки React у фронтенд-екосистемі JavaScript з'явилася абсолютно нова архітектура - Flux.

Чому команда розробників React зробила саме так? Чому такий підхід краще тих, що з'явилися раніше за нього, начебто архітектури MVC і спагетті-коду, який пишуть на jQuery? Якщо ви з тих, кого цікавлять ці питання, можете подивитися цей виступ 2013 року, присвячене розробці JavaScript-застосунків в Facebook.

У 2013 році компанія Facebook щойно завершила серйозну роботу по інтеграції в свою платформу чату. Ця нова можливість була вбудована практично в кожну сторінку проєкту, чат впливав на звичайні сценарії роботи з платформою. Це був складний застосунок, вбудований в інший застосунок, який і до цього не можна було назвати простим. Команді Facebook довелося зіткнутися з рішенням нетривіальних завдань, справляючись з неконтрольованою зміною DOM і з необхідністю забезпечити паралельну асинхронну роботу користувачів в новому середовищі.

Наприклад, як заздалегідь дізнатися про те, що буде виведено на екрані в ситуації, коли що завгодно, в будь-який час і з будь-якої причини, може звернутися до DOM і внести туди зміни? Як забезпечити правильність побудови того, що побачить користувач?

Використовуючи популярні фронтенд-інструменти, які існували до React, нічого такого не можна було гарантовано забезпечити. У ранніх веб-застосунках «стан гонок» в DOM булв однією з найпоширеніших проблем.

Відсутність детермінізму = паралельні обчислення + стан що змінюється. Мартін Одерски

Головним завданням команди розробки React було рішення цієї проблеми. Вони з нею впоралися, застосувавши два основних інноваційних підходи:

  • Односпрямована прив'язка даних з використанням архітектури Flux.
  • Незмінність стану компонента. Після того, як стан компонента встановлено, він вже не може бути змінений. Зміни стану не зачіпають візуалізовані компоненти. Замість цього подібні зміни призводять до рендеринга нового представлення, що володіє новим станом.

Найпростіший виявлений нами спосіб структурування і рендеринга компонентів, з концептуальної точки зору, полягав в тому, щоб просто прагнути до повної відсутності мутацій. Том Оччіно, JSConfUS 2013

Бібліотека React змогла серйозно знизити гостроту проблеми неконтрольованих мутацій завдяки використанню архітектури Flux. Замість того щоб приєднувати до довільної кількості довільних об'єктів (моделей) обробники подій, що викликають оновлення DOM, бібліотека React дала розробникам єдиний спосіб управління станом компонента. Це - диспетчеризація дій, що впливають на сховище даних. Коли змінюється стан сховища, система пропонує компоненту повторно візуалізуватись.

Вступ в React, якого нам не вистачало

Архітектура Flux

Коли мені задають питання про те, чому варто звернути увагу на React, я даю просту відповідь: «Справа в тому, що нам потрібен детермінований рендеринг представлень, а React значно спрощує вирішення цього завдання».

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

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

JSX

JSX - це розширення JavaScript, що дозволяє декларативно створювати компоненти користувальницького інтерфейсу. JSX володіє наступними помітними можливостями:

  • Застосування простої декларативною розмітки.
  • Код розмітки розташований там же, де і код компонента.
  • Реалізація принципу поділу відповідальностей (наприклад - відділення опису інтерфейсу від логіки стану і від побічних ефектів). Причому, реалізація, заснована не на використанні різних технологій (наприклад - HTML, CSS, JavaScript).
  • Абстрагування управління змінами DOM.
  • Абстрагування від особливостей різних платформ, для яких створюють React-застосунки. Справа в тому, що завдяки використанню React можна створювати застосунки, призначені для безлічі платформ (мова йде, наприклад, про розробку для мобільних пристроїв з використанням React Native, про застосунки для систем віртуальної реальності, про розробку для Netflix Gibbon, про створення Canvas/WebGL, про проект react-html-email ).

Якщо, до появи JSX, потрібно було декларативно описувати інтерфейси, то не можна було обійтися без використання HTML-шаблонів. В ті часи не було загальновизнаного стандарту по створенню таких шаблонів. Кожен фреймворк використовував власний синтаксис який вам доводилося вивчати щоб зробити такі речі як: пройтися в циклі за деякими даними, вбудувати в текстовий шаблон значення зі змінних або прийняти рішення про те, який компонент інтерфейсу виводити, а який - ні.

У наші дні, якщо поглянути на різні фронтенд-інструменти, виявиться, що без спеціального синтаксису, на зразок директиви *ngFor з Angular, теж не обійтися. Але, так як JSX можна назвати надмножиною JavaScript, створюючи JSX-розмітку можна користуватися існуючими можливостями JS.

Наприклад, перебрати якийсь набір елементів можна, скориставшись методом Array.prototype.map. Можна використовувати логічні оператори, організовувати умовний рендеринг за допомогою тернарного оператора. Можна користуватися чистими функціями, можна конструювати рядки з використанням шаблонних літералів, або взагалі, засобами JSX, доступні всі можливості JavaScript. Вважаю, що в цьому полягає величезна перевага React перед іншими фреймворками та бібліотеками.

Ось приклад JSX-коду:

const ItemList = ({ items }) => (
  <ul>
    {items.map((item) => (
      <li key={item.id}>
        <div>{item.name}</div>
      </li>
    ))}
  </ul>
);

Правда, при роботі з JSX потрібно враховувати деякі особливості, які, спочатку, можуть здатися незвичними.

  • Тут використовується підхід до іменування атрибутів елементів, що відрізняється від того, який прийнятий в HTML. Наприклад, class перетворюється в className. Мова йде про застосування стилю іменування camelCase.
  • У кожного елемента списку, який потрібно вивести, повинен бути постійний унікальний ідентифікатор, призначений для використання в JSX-атрибуті key. Значення ідентифікатора має залишатися незмінним в ході різних маніпуляцій з елементами списку. На практиці більшість елементів списків в моделях даних мають унікальні id, ці ідентифікатори зазвичай відмінно показують себе в ролі значень для key.

React не нав'язує розробнику єдино правильний спосіб роботи з CSS. Наприклад, компоненту можна передати JavaScript-об'єкт зі стилями, записавши його в властивість style. При такому підході більшість звичних імен стилів буде замінено на їх еквіваленти, записані за правилами camelCase. Але цим можливості по роботі зі стилями не обмежуються. На практиці я одночасно користуюся різними підходами до стилізації React-застосунків. Вибір конкретного підходу залежить від того, що саме потрібно стилізувати. Наприклад, глобальні стилі я застосовую для оформлення тем застосунків і макетів сторінок, а локальні стилі - для налаштування зовнішнього вигляду конкретного компонента.

Ось мої улюблені можливості React, що стосуються роботи зі стилями:

  • CSS-файли, які можна завантажувати в головній частині сторінки. Вони можуть використовуватися для налаштування макетів сторінок, шрифтів та інших подібних елементів. Це - надійний, працездатний механізм стилізації.
  • CSS-модулі - це CSS-файли область застосування яких обмежена локальною областю видимості. Їх можна імпортувати безпосередньо в JavaScript-файли. Для того щоб застосовувати CSS-модулі, потрібно скористатися правильно налаштованим загрузчиком модулів. У Next.js, наприклад, цей механізм активований за замовчуванням.
  • Пакет styled-jsx, який дозволяє оголошувати стилі прямо в коді React-компонентів. Це нагадує використання тега в HTML. Область видимості таких стилів можна назвати «гіперлокальною». Мова йде про те, що стилі впливають тільки на елементи, до яких вони застосовуються, і на їх дочірні елементи. При застосуванні Next.js пакетом styled-jsx можна користуватися без необхідності самостійно щось підключати і налаштовувати.

Синтетичні події

React дає в наше розпорядження обгортку SyntheticEvents, що представляє синтетичні події і призначену для уніфікації роботи з подіями DOM. Синтетичні події вельми корисні з кількох причин:

  1. Вони дозволяють згладити особливості різних платформ, пов'язані з обробкою подій. Це спрощує розробку кросбраузерних застосунків.
  2. Вони автоматично вирішують завдання з управління пам'яттю. Якщо ви, наприклад, збираєтеся створити якийсь список з нескінченної прокруткою, користуючись лише чистими JavaScript і HTML, то вам доведеться делегувати події або підключати та відключати обробники подій у міру появи і приховування елементів списку. Все це потрібно буде робити для того щоб уникнути витоків пам'яті. Синтетичні події автоматично делегуються кореневому вузлу, що призводить до того, що React-розробникам не доводиться вирішувати завдання з управління пам'яттю.
  3. В їх роботі використовуються пули об'єктів. Механізми підтримки синтетичних подій здатні генерувати тисячі об'єктів в секунду і організовувати високопродуктивну роботу з такими об'єктами. Якщо вирішувати подібні завдання, кожен раз створюючи нові об'єкти, це призведе до частої потреби у виклику збирача сміття. А це, в свою чергу, може привести до уповільнення програми, до видимих ​​затримок в роботі призначеного для користувача інтерфейсу і анімацій. Об'єкти синтетичних подій створюються заздалегідь і поміщаються в пул об'єктів. Коли потреби в події немає, воно повертається назад в пул. В результаті розробник може не турбуватися про те, що збирач сміття заблокує головний потік JavaScript, очищаючи пам'ять від непотрібними об'єктів.

Зверніть увагу на те, що через використання пулу подій до властивостей синтетичних події не можна звернутися з асинхронної функції. Для реалізації такої схеми роботи потрібно взяти дані з об'єкта події і записати їх в змінну, доступну асинхронній функції.

Життєвий цикл компонента

Концепція життєвого циклу React-компонентів орієнтована на захист стану компонента. Стан компонента не повинен змінюватися в процесі його виведення на екран. Це досягається завдяки наступній схемі роботи: стан компоненту  не повинен змінюватися поки він рендериться. Потім, завдяки подіям життєвого циклу, стає можливим застосування до нього ефектів, можна впливати на його стан, працювати з подіями.

Розуміння особливостей життєвого циклу компонентів React вкрай важливо для того щоб розробляти інтерфейси і при цьому не битися з React, а користуватися цією бібліотекою так, як задумано її розробниками. Неправильна зміна стану компонентів або читання даних з DOM зводить нанівець сильні сторони цієї бібліотеки.

У React, починаючи з версії 0.14, з'явився синтаксис описів компонентів, заснованих на класах, що дозволяє обробляти події життєвого циклу компонентів. В життєвому циклі React-компонентів можна виділити три найважливіші етапи: Mount (монтування), Update (оновлення) і Unmount (Демонтування).

Вступ в React, якого нам не вистачало

Життєвий цикл компонента

Етап Update можна розділити на три частини: Render (рендеринг), Precommit (підготовка до внесення змін в дерево DOM), Commit (внесення змін до дерево DOM).

Вступ в React, якого нам не вистачало

Структура етапу Update

Зупинимося на цих етапах життєвого циклу компонента докладніше:

  • Render - на цьому етапі життєвого циклу компонента проводиться його рендеринг. Метод компонента render() повинен являти собою детерміновану функцію, яка не має побічних ефектів. Цю функцію варто розглядати як чисту функцію, яка одержує дані з вхідних параметрів компонента і повертає JSX.
  • Precommit - на цьому етапі можна прочитати дані з DOM, користуючись методом життєвого циклу компонента getSnapShotBeforeUpdate. Це може виявитися дуже до речі, наприклад, якщо перед повторним рендерингом компонента потрібно дізнатися щось на зразок позиції скролінгу або розмірів визуализированного елемента.
  • Commit - на цій фазі життєвого циклу компонента React оновлює DOM. Тут можна скористатися методом componentDidUpdate або хуком useEffect. Саме тут можна виконувати ефекти, планувати оновлення, використовувати DOM і вирішувати інші подібні завдання.

Ден Абрамов підготував відмінну схему, яка ілюструє особливості роботи механізмів життєвого циклу компонентів.

Вступ в React, якого нам не вистачало

Життєвий цикл React-компонентів

Я вважаю, що уявлення компонентів у вигляді довгоживучих класів - це не найкраща ментальна модель React. Пам'ятайте про те, що стан React-компонентів не має змінюватися. Застарілий стан має замінюватися на новий. Кожна така заміна викликає повторний рендеринг компонента. Це дає React його, мабуть, найголовнішу і найціннішу можливість: підтримку детермінованого підходу до створення візуальних компонентів.

Подібну поведінку можна уявити собі так: при кожній візуалізації компонента бібліотека викликає детерміновану функцію, яка повертає JSX. Ця функція не повинна самостійно викликати власні побічні ефекти. Але вона, якщо їй це потрібно, може передавати React запити на виконання подібних ефектів.

Іншими словами, більшість React-компонентів має сенс представляти собі у вигляді чистих функцій, які отримують вхідні параметри і повертають JSX. Чисті функції мають наступні особливості:

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

Зверніть увагу на те, що якщо для роботи якогось компонента потрібні побічні ефекти, виконувати їх можна, користуючись useEffect або звертаючись до творця події який  переданий компоненту через вхідні параметри і дозволяє організувати обробку побічних ефектів за межами компонента.

Хуки React

У React 16.8 з'явилася нова концепція - хуки React. Це - функції, які дозволяють підключатися до подій життєвого циклу компонентів, не користуючись при цьому синтаксисом класів і не звертаючись до методів життєвого циклу компонентів. В результаті стало можливим створювати компоненти не у вигляді класів, а у вигляді функцій.

Виклик хука, в цілому, означає появу побічного ефекту - такого, який дозволяє компоненту працювати зі своїм станом і з підсистемою введення-виведення. Побічний ефект - це будь-яка зміна стану, видима за межами функції, за винятком зміни значення, що повертається функцією.

Хук useEffect дозволяє ставити побічні ефекти в чергу для їх подальшого виконання. Вони будуть викликатися в слушний час життєвого циклу компонента. Цей час може настати відразу після монтування компонента (наприклад - під час виклику методу життєвого циклу componentDidMount ), під час фази Commit (метод componentDidUpdate ), безпосередньо перед розмонтуванням компонента ( componentWillUnmount ).

Звернули увагу на те, що з одним хуком пов'язано цілих три методу життєвого циклу компонента? Справа тут в тому, що хуки дозволяють об'єднувати пов'язану логіку, а не «розкладати» її, як було до них, за різними методами життєвого циклу компонента.

Багатьом компонентам потрібно виконувати якісь дії під час їх монтування, потрібно щось оновлювати при кожному перемальовуванні компонента, потрібно звільняти ресурси відразу перед розмонтуванням компонента для запобігання витоків пам'яті. Завдяки використанню useEffect всі ці задачі можна вирішити в одній функції, не розділяючи їх рішення на 3 різних способи, не змішуючи їх код з кодом інших завдань, не пов'язаних з ними, але які теж потребують цих методів.

Ось що нам дають хуки React:

  • Вони дозволяють створювати компоненти, представлені у вигляді функцій, а не у вигляді класів.
  • Вони допомагають краще організовувати код.
  • Завдяки їм спрощується спільне використання однієї і тієї ж логіки в різних компонентах.
  • Нові хуки можна створювати, виконуючи композицію існуючих хуків (викликаючи їх з інших хуків).

В цілому, рекомендується користуватися функціональними компонентами та хуками, а не компонентами, заснованими на класах. Функціональні компоненти зазвичай компактніше компонентів, заснованих на класах. Їх код краще організований, відрізняється кращою читабельністю, краще підходить для багаторазового використання, його легше тестувати.

Компоненти-контейнери і презентаційні компоненти

Я, прагнучи поліпшити модульність компонентів і їх придатність для багаторазового використання, орієнтуюся на розробку компонентів двох видів:

  • Компоненти-контейнери - це компоненти, які підключені до джерел даних і можуть мати побічні ефекти.
  • Презентаційні компоненти - це, здебільшого, чисті компоненти, які, отримуючи на вхід одні і ті ж вхідні параметри і контекст, завжди видають один і той же JSX.

Чисті компоненти не слід ототожнювати з базовим класом React.PureComponent, який названий саме так через те, що його небезпечно використовувати для створення компонентів, які не є чистими.

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

Розглянемо особливості презентаційних компонентів:

  • Вони не взаємодіють з мережевими ресурсами.
  • Вони не зберігають дані в localStorage та не завантажують їх звідти.
  • Вони не видають непередбачуваних даних.
  • Вони не звертаються безпосередньо до поточного системного часу (наприклад, шляхом виклику методу Date.now()).
  • Вони не взаємодіють безпосередньо зі сховищем стану програми.
  • Вони можуть використовувати локальний стан компонента для зберігання чогось на кшталт даних, введених у форми, але при цьому вони повинні підтримувати можливість прийому початкового стану, що полегшує їх тестування.

Саме через останній пункту цього списку я, кажучи про презентаційні компоненти, згадав про те, що це, по більшій частині це чисті компоненти. Ці компоненти зчитують свої стани з глобального стану React. Тому хуки, такі як useState та useReducer передають в їх розпорядження неявним чином певні дані (тобто - дані, не описані в сигнатурі функції), що, з технічної точки зору, не дозволяє назвати такі компоненти «чистими». Якщо потрібно, щоб вони були б по-справжньому чистими, можна делегувати всі завдання з управління станом компоненту-контейнеру, але я вважаю, що робити цього не варто, принаймні, до тих пір, поки правильність роботи компонента можна перевірити за допомогою модульних тестів.

“Найкраще - ворог хорошого” — Вольтер

▍Компоненти-контейнери

Компоненти-контейнери - це такі компоненти, які відповідають за управління станом, за виконання операцій введення-виведення і за вирішення будь-яких інших завдань, які можна віднести до побічних ефектів. Вони не повинні самостійно рендерити якусь розмітку. Замість цього вони делегують завдання рендеринга презентаційним компонентам, а самі служать обгорткою для таких компонентів. Зазвичай компонент-контейнер в React + Redux-застосунку просто викликає mapStateToProps() і mapDispatchToProps(), після чого передає відповідні дані презентаційним компонентів. Контейнери, крім того, можуть використовуватися для вирішення деяких завдань загального характеру, про які ми поговоримо нижче.

Компоненти вищого порядку

Компонент вищого порядку (Higher Order Component, HOC) - це компонент, який приймає інші компоненти і повертає новий компонент, який реалізує новий функціонал, заснований на вихідних компонентах.

Компоненти вищого порядку функціонують, обертаючи одні компоненти іншими. Компонент-обгортка може реалізовувати якусь логіку і створювати елементи DOM. Він також може передавати  додаткові параметри, а може і не передавати.

На відміну від хуков React і від механізму render props, компоненти вищого порядку піддаються композиції з використанням стандартного підходу до композиції функцій. Це дозволяє декларативно описувати результати композиції можливостей, призначених для використання в різних місцях програми. При цьому готові компоненти не повинні знати про існування тих чи інших можливостей. Ось приклад HOC з EricElliottJS.com :

import { compose } from 'lodash/fp';
import withFeatures from './with-features';
import withEnv from './with-env';
import withLoader from './with-loader';
import withCoupon from './with-coupon';
import withLayout from './with-layout';
import withAuth from './with-auth';
import { withRouter } from 'next/router';
import withMagicLink from '../features/ethereum-authentication/with-magic-link';

export default compose(
  withEnv,
  withAuth,
  withLoader,
  withLayout({ showFooter: true }),
  withFeatures,
  withRouter,
  withCoupon,
  withMagicLink,
);

Тут показана суміш безлічі можливостей, що спільно використовуються всіма сторінками сайту. А саме, withEnv читає налаштування з змінних оточення, withAuth реалізує механізм GitHub-аутентифікації, withLoader показує анімацію під час завантаження даних користувача, withLayout({ showFooter: true }) виводить стандартний макет з «підвалом», withFeature показує налаштування, withRouter завантажує маршрутизатор, withCoupon відповідає за роботу з купонами, а withMagicLing підтримує аутентифікацію користувачів без пароля з використанням Magic.

До речі, з огляду на те, що аутентифікація користувачів за допомогою пароля застаріла, і те, що це - небезпечна практика, в наші дні варто використовувати інші методи аутентифікації користувачів.

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

import LessonPage from '../features/lesson-pages/lesson-page.js';
import pageHOC from '../hocs/page-hoc.js';
export default pageHOC(LessonPage);

У подібних компонентів вищого порядку є альтернатива, але вона являє собою сумнівну конструкцію, звану «pyramid of doom» ( «піраміда смерті») і нею краще не користуватися. Ось як це виглядає:

import FeatureProvider from '../providers/feature-provider';
import EnvProvider from '../providers/env-provider';
import LoaderProvider from '../providers/loader-provider';
import CouponProvider from '../providers/coupon-provider';
import LayoutProvider from '../providers/layout-provider';
import AuthProvider from '../providers/auth-provider';
import RouterProvider from '../providers/RouterProvider';
import MagicLinkProvider from '../providers/magic-link-provider';
import PageComponent from './page-container';


const WrappedComponent = (...props) => (
  <EnvProvider { ...props }>
    <AuthProvider>
      <LoaderProvider>
        <LayoutProvider showFooter={ true }>
          <FeatureProvider>
            <RouterProvider>
              <CouponProvider>
                <MagicLinkProvider>
                  <YourPageComponent />
                </MagicLinkProvider>
              </CouponProvider>
            </RouterProvider>
          </FeatureProvider>
        </LayoutProvider>
      </LoaderProvider>
    </AuthProvider>
  </EnvProvider>
);

І це доведеться повторити на кожній сторінці. А якщо треба буде щось в цій конструкції змінити, то зміни в ній доведеться вносити всюди, де вона присутня. Вважаю що недоліки такого підходу абсолютно очевидні.

Використання композиції для вирішення завдань загального характеру - це один з кращих способів зменшення складності коду застосунків. Композиція - це настільки важливо, що я навіть написав про це книгу.

Підсумки

  • Чому React? React дає нам детермінований рендеринг візуальних уявлень компонентів, в основі якого лежить однонаправлена ​​прив'язка даних і незмінний стан компонентів.
  • JSX дає нам можливість простого декларативного опису інтерфейсів в JavaScript-коді.
  • Синтетичні події згладжують крос-платформні відмінності систем обробки подій і полегшують керування пам'яттю.
  • Концепція життєвого циклу компонентів спрямована на захист стану компонентів. Життєвий цикл компонента складається з фаз монтування, оновлення і размонтирования. Фаза оновлення складається з фази рендеринга, фази підготовки до внесення змін в DOM і фази внесення змін до DOM.
  • Хуки React дозволяють підключатися до методів життєвого циклу компонентів без використання синтаксису, заснованого на класах. Застосування хуків полегшує спільне використання одного і того ж коду в різних компонентах.
  • Компоненти-контейнери і презентаційні компоненти дозволяють відокремити завдання формування візуального представлення інтерфейсів від завдань з управління станом застосунку та від побічних ефектів. Це покращує можливості по багаторазовому використанню і тестування компонентів і бізнес-логіки застосунку.
  • Компоненти вищого порядку спрощують спільне використання можливостей, що представляють собою композицію інших можливостей. При цьому компонентам не потрібно знати про ці можливості (і не потрібно, щоб компоненти були б тісно пов'язані з ними).

Що далі?

У цьому матеріалі про React ми торкнулися безліч концепцій функціонального програмування. Якщо ви прагнете до глибокого розуміння принципів розробки React-застосунків, вам корисно буде освіжити свої знання про чисті функції, про іммутабельність, про карінг і частковому застосуванні функцій, про композиції функцій. Відповідні матеріали ви можете знайти на EricElliottJS.com.

Я рекомендую використовувати React спільно з ReduxRedux-Saga і RITEway. Redux рекомендується використовувати спільно з Autodux і Immer. Для організації складних схем роботи зі станом можна спробувати скористатися Redux-DSM.

Коли ви розберетеся з основами і будете готові до створення реальних React-застосунків, зверніть увагу на Next.js і Vercel. Ці інструменти допоможуть автоматизувати налаштування системи збирання проекту і CI/CD-конвеєра, з їх допомогою можна підготувати проєкт до оптимізованого розгортання на сервері. Вони дають той же ефект, що і ціла команда DevOps-фахівців, але користуватися ними можна абсолютно безкоштовно.

Які допоміжні інструменти ви застосовуєте при розробці React-застосунків?

Джерело ENG: medium.com

Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Війти / Зареєструватися