Редакс в реальному житті

Редакс в реальному житті

Доповідь розповідає про реальні проблеми, з якими ви зіткнетеся при розробці програми: як обробляти сайд-ефекти, куди поміщати бізнес-логіку і як тестувати додаток. На початку доповіді - короткий вступ в Редакс.

Редакс в реальному житті

Це - Ден Абрамов. У нього 27К передплатників (це круто). І в минулому році він зробив редакс. Редакс - це бібліотека для організації архітектури додатку.
  • Редакс в реальному житті

    Головні відмінності редакса від інших підходів - це те, що 1) все стан додатки зберігається в єдиному місці ...
  • Редакс в реальному житті

    Редакс в реальному житті

    Як я вже сказав, все стан додатки зберігається в єдиному місці. Це місце називається «стор». Наприклад, у такого додатка, яке показує цифру.
  • Редакс в реальному житті

    стор може бути таким.
  • Редакс в реальному житті

    Другий принцип - стан додатки можна змінювати безпосередньо.
  • Редакс в реальному житті

    Редакс в реальному житті

    Третій принцип - все зміни обробляються функцією, яка називається «редьюсер» і яка повинна бути чистою. Ще раз: екшен - це подія, яка генерується функцією dispatch ().
  • Редакс в реальному житті

    Чистий функція - це функція, яка завжди для одного і того ж вхідного значення повертає однаковий результат + не змінює нічого зовні себе. Синус - чиста функція, тому що для одного і того ж кута вона завжди повертає одне і те ж значення. parseInt () - чиста. $ .ajax () - не чиста, тому що в різні моменти часу вона може повернути різні значення.
  • Редакс в реальному житті

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

    Редакс в реальному житті

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

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

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

    Насправді мідлвейров може бути багато, і тоді вони організовуються по ланцюжку.
  • Редакс в реальному житті

    Фактично, мідлвейр - це просто функція, яка приймає поточний стор, який іде на ланцюжку мідлвейр і поточний екшен і щось робить з ним. Мідлвейри підключаються при створенні стору. createStore і applyMiddleware - це методи редакса. Я не буду розповідати, як писати свій мідлвейр, тому що створювати свій міддлвейр для роботи з сайд-ефектами - занадто складно. Замість цього ми подивимося на ті рішення, які вже є. До слова, мідлвейри створюються спільнотою і не входять в поставку редакса.
  • Є купа методів організації сайд-ефектів. Я знаю два. Перший - це redux-thunk, з яким ви, створюючи додаток з редаксом, зіткнетеся точно. Навіщо він потрібен? Класичний редакс вміє працювати тільки з екшеном, які представлені простими об'єктами.
  • Застосовуючи мідлвейр redux-thunk ось таким ось чином.
  • Редакс в реальному житті

    ви отримуєте можливість замість простих об'єктів.
  • Редакс в реальному житті

    ... діспатчіть функції. Коли ви задіспатчіте функцію, redux-thunk викличе її і передасть в неї метод dispatch стору, який ви потім зможете викликати тоді, коли вам потрібно. Такі функції називаються thunk-ами.
  • Або ось так, якщо винести створення екшену в окрему функцію. Таке винесення, до речі, - стандартний шаблон в Редаксе, і функція, що створює екшен, називається екшен-кріейтор.
  • Що ще можна робити з redux-thunk? Можна діспатчіть кілька екшенів поспіль, щоб виконати логаут і потім очистити стор.
  • Редакс в реальному житті

    Можна діспатчіть екшени за таймером, щоб побесишь користувача спливаючими модальними вікнами. Можна робити що завгодно, тому що у нас є dispatch - і навіть є поточний стан стору, яке передається другим параметром. Redux-thunk зручний для простих сайд-ефектів. Коли потрібно організувати складний потік сайд-ефектів, він стає незручний. В цьому випадку пригождается redux-saga.
  • Що таке redux-saga? Взагалі, сага - це підхід, що прийшов з бекенда. Redux-saga - це альтернативний підхід до організації сайд-ефектів. Замість того, щоб діспатчіть функції, які обробляються redux-thunk-му, ви створюєте сагу, яка збирає всю логіку обробки всередину себе. На відміну від thunk-ів, які виконуються, коли ви їх діспатчіте, саги запускаються при старті програми та як би «працюють в тлі». Саги слухають все екшени, які діспатчіт стор, і вирішують, що робити з ними. І у саг в редаксе дві переваги в порівнянні з thunk-ами: - Вони дозволяють організовувати складні послідовності сайд-ефектів - І вони дуже легко тестуються Давайте подивимося, як виглядає сага.
  • Редакс в реальному житті

    Пам'ятаєте старий приклад логіна за допомогою thunk-а? Давайте змінимо його на сагу.
  • Редакс в реальному житті

    Що змінюється? - Функція стає генератором - Прямі виклики замінюються на непрямі, через call (); dispatch () замінюється на put () - Стиль викликів змінюється на синхронний (без колбек) - і саме ось це дозволяє писати складні асинхронні запити
  • На екшени можна підписуватися двома способами. Перший - простий: ми обертаємо сагу і просимо redux-saga викликати її кожен раз, коли відбудеться екшен LOGIN_REQUESTED.
  • Другий спосіб складніший. Ми поміщаємо код саги в нескінченний цикл і розміщуємо на початку yield take ( 'LOGIN_REQUESTED'). Коли сага почне виконуватися, виконання дійде до цього рядка, зупиниться і не продовжиться до тих пір, поки не згенерує екшен LOGIN_REQUESTED.
  • Редакс в реальному житті

    Другий спосіб дозволяє ловити кілька екшенів. Тут код на місці трьох крапок виконається тільки тоді, коли відбудеться ANOTHER_ACTION. якому передував LOGIN_REQUESTED.
  • Так саги встановлюються. Вони запускаються відразу після виклику createStore (). Приклади коду з сагами
  • Редакс в реальному житті

    З бізнес-логікою все просто.
  • Бізнес-логіку - мідлвейрам! Чому? - Сайд-ефекти, яким належить велика частина бізнес-логіки (thunk-ах або сагах), і так будуть в мідлвейрах. Є сенс перенести залишилася бізнеслогіку туди - Мідлвейри мають доступ до всього сторі, а редьюсери - тільки до частини - Можна діспатчіть кілька екшенів Ще посилання: Question: Where to put business logic / validations? Recommendations for best practices regarding action-creators, reducers, and selectors
  • Редакс в реальному житті

    Тобто на цій схемі бізнес-логіка повинна знаходитися в цьому чорному блоці.
  • Приклад коду з одного з кращих open-source проектів на редаксе. Редьюсери в ньому максимально прості, ...
  • а екшен-кріейтори складні і містять всю логіку.
  • Що взагалі можна тестувати в Редаксе? Звичайні екшен-крійетори тестувати просто. Асинхронні - складно, тому що вони повертають функції, а перевірити, що повернулася правильна функція, складно. Редьюсери - просто. (Як тестувати: екшен-кріейтори. Асинхронні екшен-кріейтори. Редьюсери.)
  • Я розповім про те, як тестувати саги. Саги тестувати дуже просто.
  • Пам'ятаєте цей слайд? Самий кайф - ось в цих виділених функціях.
  • call ($. ajax) не викликає $ .ajax безпосередньо, а генерує декларативне опис виклику у вигляді простого JS-об'єкта. Завдяки цьому для тестування досить порівняти два об'єкти через deepEqual.
  • Ось таку от сагу ...
  • ... протестувати дуже просто. Зверніть увагу, що для того, щоб семуліровать відповідь сервера, ми просто передаємо його в генератор. І перевірити те, що генератор викликає $ .ajax і робить цим запит на сервер, дуже просто, тому що генератор повертає об'єкт з описом виклику.
  • Тобто ще раз: ми декларуємо виклик AJAX-запиту ...
  • ... і просто порівнюємо декларацію. Точно так само і з генерацією екшенів. Якщо ми хочемо перевірити, що сага згенерує екшен LOGIN_SUCCESS. ми просто порівнюємо ту декларацію, яку повернув генератор, з очікуваної.
  • Редакс в реальному житті

    Редакс в реальному житті

    Редакс в реальному житті

    Редакс в реальному житті

    Схожі статті