React for Universal Apps,

next step for JS to Server-side

Roman Iakobchuk

Повернемось в еру динозаврів

  • Заходимо на абстрактний сайт
  • Натискаємо абстрактний лінк (нехай пунк меню)
  • Йдемо заварювати чай

Тим часом,
десь під капотом

  • Браузер встановлює з'єднання із сервером
  • Відправляє GET запит
  • Сервер обробляє запит, збирає необхідні данні
  • Будує HTML
  • Відправляє його як відповідь
  • Браузер будує новий DOM
  • Браузер рендерить цей новий DOM

Інтернет змінився

  • Інтернет став швидше
  • Сервера стали швидше
  • Браузери стали швидше
  • Ми навчились кешувати і оптимізовувати

Але і вимоги зросли

Для бізнесу кожен клік - втрата частини клієнтів

SPA vs Classic

  • Значно кращий UX
  • Уніфікація мобільних і браузерних UI
  • Помітно вища швидкість роботи
  • Простота розробки
  • Швидше первинне завантаження
  • Індексація пошуковими роботами

А може краще так?

  • Значно кращий UX
  • Уніфікація мобільних і браузерних UI
  • Помітно вища швидкість роботи
  • Простота розробки
  • Швидше первинне завантаження
  • Індексація пошуковими роботами

Що робити?

Universal App
=

SPA
+
Server-rendering

Як робити

('Currently, the set of Ember applications supported is extremely limited')

React

React.renderToString(<App {...initialState} />)

React.render(<App {...initialState} />, container)

React - не SPA фреймворк

  • Робота з данними
  • Комунікації з API
  • Роутинг

React - лише View

Інфраструктура

frameworks-friendly

React-way

MVVM vs Flux

Мінуси Facebook Flux

  • Dispatcher як Singleton
  • Вся архітектура на сайд-ефектах
  • Це не фреймворк, це бібліотечка Pub/Sub

Чого хотілось би?

State 

UI 

Pure Function

Які варіанти?

  • Flux а-ля MVC
  • Flux а-ля FRP
  • ...
  • 100500 інших flux-бібліотек
  • Redux.js

Давайте відволічемось

Казковий світ ФП

0. Функції - first-class citizens

1. Чисті функції

2. Іммутабельні данні

Redux - FRP для чайників

Звична
Event-driven
Architecture

FRP
Architecture

Action-creators

Як чисті функції

  • Відсутній диспечер
  • Повертає Action як плоский об'єкт
function increment(amount) {
    return {
        type: INCREMENT,
        data: {amount}
    }
}

Stores => Reducers

Як чисті функції

function counter(number = 0, action) {
    const {type, data} = action
    return type == INCREMENT ? number + data.amount : number
}
  • не зберігають стан
  • не залежать від оточення

Store

Як Immutable object

Current State

Final State

New State

Action

New State

Action

Action

FP - стиль

function pow(n, p) {
    let i = 0,
        res = 1;
    for (;i < p; i++) {
        res *= n
    }
    return res;
}
function pow(n, p) {
    return p == 0 ? 1 : 
                    n * pow(n, p -1)
}
function pow(n, p, acc = 1) {
    return p == 0 ? acc : 
                    pow(n, p - 1, acc * n)
}

Е, а де сайд-ефекти?

  • API calls
  • Logging
  • Reporting
  • ...

Middleware

Redux flow

Action Creator

Middlewares

Reducers

Store

UI

dispatch

Side-effects

Middleware

  • Централізовані сайд-ефекти
  • Єдина відмінність
    - серверу від клієнту,
    - продакшину від девелопменту
  • Єдиний Code-base!

Що було на сервері

  • Серверний роутинг
  • Серверний рендеринг
  • API
  • Статика
  • Сервіси
  • ...

Клієнт став надтовстим

Приходьте на МК

Best practice SPA

using React

Робіть круті проекти

Роман Якобчук

Skype: r.iakobchuk

Email: r.iakobchuk@gmail.com