React, ReactRouter, Redux, redux-observable · renderDays() { let days =...

133
React, ReactRouter, Redux, redux-observable Алексей Охрименко IPONWEB, Москва

Transcript of React, ReactRouter, Redux, redux-observable · renderDays() { let days =...

Page 1: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

React, ReactRouter, Redux, redux-observable

Алексей ОхрименкоIPONWEB, Москва

Page 2: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Алексей Охрименко

?

Page 3: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

IPONWEB

Page 4: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

14

Page 5: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 6: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

React компоненты

Page 7: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

create-react-app calendar

Page 8: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

render() { return [ <div className="month"> <ul> <li className="prev">&#10094;</li> <li className="next">&#10095;</li> <li><div>August</div><span>2017</span></li> </ul> </div>, <ul className="weekdays"> <li>Mo</li> </ul>, <ul className="days"> <li>1</li> </ul> ]; }

Page 9: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

render() { return [ <div className="month"> <ul> <li className="prev">&#10094;</li> <li className="next">&#10095;</li> <li><div>August</div><span>2017</span></li> </ul> </div>, <ul className="weekdays"> <li>Mo</li> </ul>, <ul className="days"> <li>1</li> </ul> ]; }

Page 10: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

render() { return [ <div className="month"> <ul> <li className="prev">&#10094;</li> <li className="next">&#10095;</li> <li><div>August</div><span>2017</span></li> </ul> </div>, <ul className="weekdays"> <li>Mo</li> </ul>, <ul className="days"> <li>1</li> </ul> ]; }

Page 11: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

render() { return [ <div className="month"> <ul> <li className="prev">&#10094;</li> <li className="next">&#10095;</li> <li><div>August</div><span>2017</span></li> </ul> </div>, <ul className="weekdays"> <li>Mo</li> </ul>, <ul className="days"> <li>1</li> </ul> ]; }

Page 12: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

render() { return [ <div className="month"> <ul> <li className="prev">&#10094;</li> <li className="next">&#10095;</li> <li><div>August</div><span>2017</span></li> </ul> </div>, <ul className="weekdays"> <li>Mo</li> </ul>, <ul className="days"> <li>1</li> </ul> ]; }

Page 13: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 14: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 15: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

constructor() { super(); let now = new Date(); this.state = { year: now.getFullYear(), month: now.getMonth() + 1 } this.next = this.next.bind(this); this.prev = this.prev.bind(this); }

Page 16: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

constructor() { super(); let now = new Date(); this.state = { year: now.getFullYear(), month: now.getMonth() + 1 } this.next = this.next.bind(this); this.prev = this.prev.bind(this); }

Page 17: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

next() { this.setState(getNextYearMonth(this.state.year, this.state.month)); } prev() { this.setState(getPrevYearMonth(this.state.year, this.state.month)); }

Page 18: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

render() { return [ <div className="month"> <ul> <li className="prev">&#10094;</li> <li className="next">&#10095;</li> <li><div>August</div><span>2017</span></li> </ul> </div>, <ul className="weekdays"> <li>Mo</li> </ul>, <ul className="days"> <li>1</li> </ul> ]; }

Page 19: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

<div className="month" key="month"> <ul> <li onClick={this.prev} className="prev">&#10094;</li> <li onClick={this.next} className="next">&#10095;</li> <li> <div>{getFullMonthName(this.state.month)}</div> <div>{this.state.year}</div> </li> </ul> </div>,

Page 20: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

<div className="month" key="month"> <ul> <li onClick={this.prev} className="prev">&#10094;</li> <li onClick={this.next} className="next">&#10095;</li> <li> <div>{getFullMonthName(this.state.month)}</div> <div>{this.state.year}</div> </li> </ul> </div>,

Page 21: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

<ul className="weekdays" key="weekdays"> <li>Mo</li> <li>Tu</li> <li>We</li> <li>Th</li> <li>Fr</li> <li>Sa</li> <li>Su</li> </ul>,

Page 22: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

this.renderDays()

Page 23: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month); let items = new Array(days).fill().map((_, index) => { let cls = index === 0 ? 'skip' + skip : ''; return <li className={cls} key={index}>{index + 1}</li> }); return ( <ul className="days" key="days"> {items} </ul> ) }

Page 24: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month); let items = new Array(days).fill().map((_, index) => { let cls = index === 0 ? 'skip' + skip : ''; return <li className={cls} key={index}>{index + 1}</li> }); return ( <ul className="days" key="days"> {items} </ul> ) }

Page 25: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month); let items = new Array(days).fill().map((_, index) => { let cls = index === 0 ? 'skip' + skip : ''; return <li className={cls} key={index}>{index + 1}</li> }); return ( <ul className="days" key="days"> {items} </ul> ) }

Page 26: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month); let items = new Array(days).fill().map((_, index) => { let cls = index === 0 ? 'skip' + skip : ''; return <li className={cls} key={index}>{index + 1}</li> }); return ( <ul className="days" key="days"> {items} </ul> ) }

Page 27: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

let items = new Array(days).map(() => 1)

Page 28: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

let items = new Array(days).fill().map(() => 1)

Page 29: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

null, undefined

Page 30: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

null, undefined, undefined value

Page 31: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Sparse Arrayhttps://github.com/codemix/fast.js

Page 32: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month); let items = new Array(days).fill().map((_, index) => { let cls = index === 0 ? 'skip' + skip : ''; return <li className={cls} key={index}>{index + 1}</li> }); return ( <ul className="days" key="days"> {items} </ul> ) }

Page 33: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month); let items = new Array(days).fill().map((_, index) => { let cls = index === 0 ? 'skip' + skip : ''; return <li className={cls} key={index}>{index + 1}</li> }); return ( <ul className="days" key="days"> {items} </ul> ) }

Page 34: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month); let items = new Array(days).fill().map((_, index) => { let cls = index === 0 ? 'skip' + skip : ''; return <li className={cls} key={index}>{index + 1}</li> }); return ( <ul className="days" key="days"> {items} </ul> ) }

Page 35: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 36: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

constructor() { super(); let now = new Date(); this.state = { year: now.getFullYear(), weekNumber: getWeekNumber(now) } this.next = this.next.bind(this); this.prev = this.prev.bind(this); }

Page 37: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

constructor() { super(); let now = new Date(); this.state = { year: now.getFullYear(), weekNumber: getWeekNumber(now) } this.next = this.next.bind(this); this.prev = this.prev.bind(this); }

constructor() { super(); let now = new Date(); this.state = { year: now.getFullYear(), month: now.getMonth() + 1 } this.next = this.next.bind(this); this.prev = this.prev.bind(this); }

Page 38: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

constructor() { super(); let now = new Date(); this.state = { year: now.getFullYear(), weekNumber: getWeekNumber(now) } this.next = this.next.bind(this); this.prev = this.prev.bind(this); }

constructor() { super(); let now = new Date(); this.state = { year: now.getFullYear(), month: now.getMonth() + 1 } this.next = this.next.bind(this); this.prev = this.prev.bind(this); }

Page 39: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

CalendarContainer.js

constructor() { super(); let now = new Date(); this.state = { year: now.getFullYear(), month: now.getMonth() + 1, weekNumber: getWeekNumber(now) } }

Page 40: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Container / Page / Atomic Design

constructor() { super(); let now = new Date(); this.state = { year: now.getFullYear(), month: now.getMonth() + 1, weekNumber: getWeekNumber(now) } }

Page 41: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

CalendarContainer.js

return [ <Month year={this.state.year} month={this.state.month}></Month>, <Week year={this.state.year} month={this.state.weekNumber}></Week> ];

Page 42: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Умные/Глупые компоненты

Page 43: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Коммуникация между компонентами

React

ROOT

TARGET

Components Props

Page 44: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Коммуникация между компонентами

React

ROOT

TARGET

Components Props

Page 45: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Коммуникация между компонентами

React

ROOT

TARGET

Components Props

Page 46: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Коммуникация между компонентами

React

ROOT

TARGET

Components Props

Page 47: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 48: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 49: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 50: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

React Router - на рану

Page 51: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

import { BrowserRouter } from 'react-router-dom'

ReactDOM.render(( <BrowserRouter> <App /> </BrowserRouter> ), document.getElementById('root'))

Page 52: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

<Switch> <Route exact path='/' component={Month}/> <Route path='/week' component={Week}/> </Switch>

Page 53: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 54: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 55: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Кто не использует Router?

Page 56: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 57: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

… у вас возможно уважительные причины

Page 58: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 59: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

«About Page»

Page 60: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Состояние приложения

Page 61: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Состояние приложения != Состояние компонента

Page 62: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Состояние приложения != this.setState

Page 63: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 64: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Cостояние

Page 65: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 66: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Состояние приложения - это одно из главных отличий Frontend от Backend

Page 67: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

https://www.youtube.com/watch?v=udNHwANuicU

State Managers

Page 68: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Redux

Page 69: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Dan Abramov

Данила Абрамов

Page 70: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 71: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Коммуникация между компонентами

React

ROOT

TARGET

Page 72: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Коммуникация между компонентами

React

ROOT

TARGET

Store

ReduxDispatch

Page 73: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Коммуникация между компонентами

React

ROOT

TARGET

Store

ReduxDispatch

Subscribe

Page 74: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Коммуникация между компонентами

React

ROOT

TARGET

Store

ReduxDispatch

Subscribe

Page 75: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Умные/Глупые компоненты все-равно нужно использовать

Page 76: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Увы в коде ничего проще не становиться

Page 77: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Reducers, Action, Store, ActionCreators синхронны :(

Page 78: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

SideEffect Managers

Page 79: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

SideEffect Managers

●thunk ●redux-saga ●redux-loop ●redux-observable

Page 80: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

SideEffect Managers

●thunk ●redux-saga ●redux-loop ●redux-observable

Page 81: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Promise

Page 82: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return 1; }

function b() { return a() + 2; }

console.log(b());

Page 83: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return 1; }

function b() { return a() + 2; }

console.log(b());

Page 84: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return 1; }

function b() { return a() + 2; }

console.log(b());

Page 85: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return new Promise((resolve, reject) => { resolve(1); }); }

function b() { return a().then((v) => v + 2); }

b().then(console.log)

Page 86: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return new Promise((resolve, reject) => { resolve(1); }); }

function b() { return a().then((v) => v + 2); }

b().then(console.log)

Page 87: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return new Promise((resolve, reject) => { resolve(1); }); }

function b() { return a().then((v) => v + 2); }

b().then(console.log)

Page 88: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Проблемы Promise

●Одно значение

Page 89: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Проблемы Promise

●Одно значение ●Отмена

Page 90: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Проблемы Promise

●Одно значение ●Отмена ●Повтор

Page 91: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Проблемы Promise

●Одно значение ●Отмена ●Повтор ●Отсутствие синхронности

Page 92: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Проблемы Promise

●Одно значение ●Отмена ●Повтор ●Отсутствие синхронности ●Finally *

Page 93: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Observable

Page 94: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return [1]; }

function b() { return a().map((v) => v + 2); }

console.log(b());

Page 95: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return [1]; }

function b() { return a().map((v) => v + 2); }

console.log(b());

Page 96: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return [1]; }

function b() { return a().map((v) => v + 2); }

console.log(b());

Page 97: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); done(); }); }

function b() { return a().map((v) => v + 2); }

b().subscribe(console.log);

Page 98: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); done(); }); }

function b() { return a().map((v) => v + 2); }

b().subscribe(console.log);

Page 99: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); done(); }); }

function b() { return a().map((v) => v + 2); }

b().subscribe(console.log);

map, filter, scan

Page 100: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); done(); }); }

function b() { return a().map((v) => v + 2); }

b().subscribe(console.log);

delay, debounce, throttle

Page 101: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); done(); }); }

function b() { return a().map((v) => v + 2); }

b().subscribe(console.log);

Page 102: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); done(); }); }

function b() { return a().map((v) => v + 2); }

b().subscribe(console.log);

Page 103: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); done(); }); }

function b() { return a().map((v) => v + 2); }

b().subscribe(console.log);

Hot vs Cold

Page 104: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Higher Order Observable

Page 105: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Promise.all, Promise.race

Page 106: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); next(2); done(); }); }

function b() { return a().switchMap((v) => ajax.get('/api')); }

b().subscribe(console.log);

Page 107: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); next(2); done(); }); }

function b() { return a().switchMap((v) => ajax.get('/api')); }

b().subscribe(console.log);

Page 108: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); next(2); done(); }); }

function b() { return a().switchMap((v) => ajax.get('/api')); }

b().subscribe(console.log);

Page 109: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); next(2); done(); }); }

function b() { return a().switchMap((v) => ajax.get('/api')); }

b().subscribe(console.log);

Page 110: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); next(2); done(); }); }

function b() { return a().switchMap((v) => ajax.get('/api')); }

b().subscribe(console.log);

Page 111: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

function a() { return Observable.create(function(next, error, done) { next(1); next(2); done(); }); }

function b() { return a().switchMap((v) => ajax.get('/api')); }

b().subscribe(console.log);

Page 112: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

RxJs - это lodash для Observableъ

> 130 методов

Page 113: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

redux-observable

Page 114: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

import { ajax } from 'rxjs/observable/dom/ajax';

const fetchEpic = action$ => action$.ofType(FETCH) .switchMap(action => ajax.getJSON(`/api/${action.payload}`) .map(response => fetchFulfilled(response)) .catch(error => Observable.of({ type: FETCH_REJECTED, payload: error.xhr.response, error: true })) );

Page 115: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

import { ajax } from 'rxjs/observable/dom/ajax';

const fetchEpic = action$ => action$.ofType(FETCH) .switchMap(action => ajax.getJSON(`/api/${action.payload}`) .map(response => fetchFulfilled(response)) .catch(error => Observable.of({ type: FETCH_REJECTED, payload: error.xhr.response, error: true })) );

Page 116: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

import { ajax } from 'rxjs/observable/dom/ajax';

const fetchEpic = action$ => action$.ofType(FETCH) .switchMap(action => ajax.getJSON(`/api/${action.payload}`) .map(response => fetchFulfilled(response)) .catch(error => Observable.of({ type: FETCH_REJECTED, payload: error.xhr.response, error: true })) );

Page 117: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

import { ajax } from 'rxjs/observable/dom/ajax';

const fetchEpic = action$ => action$.ofType(FETCH) .switchMap(action => ajax.getJSON(`/api/${action.payload}`) .map(response => fetchFulfilled(response)) .catch(error => Observable.of({ type: FETCH_REJECTED, payload: error.xhr.response, error: true })) );

Page 118: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

import { ajax } from 'rxjs/observable/dom/ajax';

const fetchEpic = action$ => action$.ofType(FETCH) .switchMap(action => ajax.getJSON(`/api/${action.payload}`) .map(response => fetchFulfilled(response)) .catch(error => Observable.of({ type: FETCH_REJECTED, payload: error.xhr.response, error: true })) );

Page 119: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

import { ajax } from 'rxjs/observable/dom/ajax';

const fetchEpic = action$ => action$.ofType(FETCH) .switchMap(action => ajax.getJSON(`/api/${action.payload}`) .map(response => fetchFulfilled(response)) .catch(error => Observable.of({ type: FETCH_REJECTED, payload: error.xhr.response, error: true })) );

Page 120: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

import { ajax } from 'rxjs/observable/dom/ajax';

const fetchEpic = action$ => action$.ofType(FETCH) .switchMap(action => ajax.getJSON(`/api/${action.payload}`) .map(response => fetchFulfilled(response)) .catch(error => Observable.of({ type: FETCH_REJECTED, payload: error.xhr.response, error: true })) );

Page 121: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Очень умная очередь запросов

Page 122: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

.debounce(1000)

.distinctUntilChanged()

.switchMap(…)

Дожидаемся реальных изменений

Page 123: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

.retry(3)

500

Page 124: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

.retryWhen(function (errors) { return Observable .zip( Observable.range(1, MAX_RETRIES), errors, (i, e) => i ) .flatMap((i) => Observable.timer(i * 1000)); })

Exponential Backoff

Page 125: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);
Page 126: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Послесловие…

Page 127: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

1) React компоненты (create-react-app)

Page 128: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

1) React компоненты (create-react-app) 2) Умные/Глупые компоненты

Page 129: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

1) React компоненты (create-react-app) 2) Умные/Глупые компоненты 3) Router

Page 130: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

1) React компоненты (create-react-app) 2) Умные/Глупые компоненты 3) Router 4) State Manager ( Redux … )

Page 131: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

1) React компоненты (create-react-app) 2) Умные/Глупые компоненты 3) Router 4) State Manager ( Redux … ) 5) Redux -> SideEffect Manager -> ReduxObservable

Page 132: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

1) React компоненты (create-react-app) 2) Умные/Глупые компоненты 3) Router 4) State Manager ( Redux … ) 5) Redux -> SideEffect Manager -> ReduxObservable 6) Observable / 2 > Promise

Page 133: React, ReactRouter, Redux, redux-observable · renderDays() { let days = getDaysInMonth(this.state.year, this.state.month); let skip = getFirstDayWeekday(this.state.year, this.state.month);

Twitter: Ai_boy http://bit.ly/2G05fuo

Алексей Охрименко