Нажми пробел чтобы продолжить
Стрелка вправо — для быстрой промотки
3. Многоразовые компоненты
2. Просто отладить
1. Легко понять
// on button click
function onCancel(){
store.dispatch({
type: 'ORDER_UPDATE_CANCEL_REQUESTED',
orderId
})
}
// on button click
function onSubmit(){
updateOrder({
orderId,
onSuccess: updateQuote,
})
}
function updateQuote(orderId){
store.dispatch({
type: 'INSTANT_QUOTE_REQUESTED',
orderId
})
let request = fetchAPI('/quote/update', {
userId,
orderId
})
// ...
}
request.then(function(data){
if (data.status == 4000005){
store.dispatch({type: 'USER_LOGOUT'})
store.dispatch({type: 'AUTH_REQUESTED'})
}
})3. Сделать еще одно приложение ― для мастеров
1. Упаковать сайт в формат виджета для сайтов партнеров
2. Упаковать в PhoneGap приложение
1. отобразить прелоадер
2. загрузить заказ с сервера
3. показать форму заказа
4. дождаться ввода пользователя
5. отправить данные на сервер
6. отобразить ошибки
7. repeat until
// 1. отобразить прелоадер
mountPage('preloader-page')// 2. загрузить заказ с сервера
let response = yield fetch(`/order/${id}`)// 3. показать форму заказа
let pageChannel = mountPage('order-page')let order = yield response.json()
store.dispatch({
type: 'ORDER_FETCHED',
payload: order
})// 4. дождаться ввода пользователя
let formData = yield take(pageChannel)// 5. отправим данные на сервер
let response = yield fetch(`/order/${id}`,{
method: 'POST',
body: JSON.stringify(formData),
})
let errors = yield response.json()if (!errors.length)
return window.location = '/payment'
// 6. отобразить ошибки
store.dispatch({
type: 'ERRORS_OCCURRED',
errors
})// 7. repeat until
// TODO обернуть код в while(true){}// Поместить весь код в function*(){}function* runAndWait() {
console.log('Готов к работе')
let serverData = yield {
command: 'waitForServerResponse',
promise: fetch('/orders'),
} // ...
} let userData = yield {
command: 'waitForUserInput',
}
yield promiseObj
yield take(channel)let task = yield fork(coroutine)yield join(task)yield cancel(task)/catalog
function* runCatalogPage/cart
function* runCartPagefunction* updateOrder/payment
function* runCatalogPagefunction* updateQuote
--> function* handleCommonAPIErrors
----> function* runCartPage------> function* fetchAPI--------> throw new APIError({code: 500002})
function decorate(coroutine){
function* wrappedCoroutine(){
try {
yield* coroutine()
} catch(error) {
// handle error
}
}
return wrappedCoroutine
}
const wrappedRunCartPage = decorate(runCartPage)try {
yield* runPage()} catch(exception) {
if (exception instanceof OrderNotFound){
mountPage('order-not-found')
}
// ...try {
yield* runPage()} catch(exception) {
if (exception instanceof LoginRequired){
window.location = '/signin'
}
// ...
}try {
yield* runPage(...args)
} catch(exception) {
Raven.captureException(exception)
mountPage('error-page')
}Store
React
== Model
== View + Controller
Store
React
Coroutine
select
channel.put
View
Controller
способность наращивать функционал
в коде легко ориентироваться
меньше бойлерплейта
Hot Module Replacement
CTO веб-сервиса МойМеханик.рф
email pelid80@gmail.com
skype evseev.evgeny