strategies for mitigating complexity in react based redux applicaitons

71
HELLO, REACT.JS VANCOUVER!

Upload: garbles

Post on 03-Mar-2017

103 views

Category:

Engineering


4 download

TRANSCRIPT

Page 1: Strategies for Mitigating Complexity in React Based Redux Applicaitons

HELLO,REACT.JS VANCOUVER!

Page 3: Strategies for Mitigating Complexity in React Based Redux Applicaitons
Page 4: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Strategies for Mitigating Complexity in React

Based Redux Applications

Page 5: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Designing for Simplicity

Page 6: Strategies for Mitigating Complexity in React Based Redux Applicaitons

"The computing scientist’s main challenge is not to get confused by the complexities of his own making."

- E. W. Dijkstra

Page 7: Strategies for Mitigating Complexity in React Based Redux Applicaitons

"The bottom line is that simplicity is a choice. It's your fault if you don't have a simple system."

- Rich Hickey (Simple Made Easy)

Page 8: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Tests

Page 9: Strategies for Mitigating Complexity in React Based Redux Applicaitons

"Complexity is the root cause of the vast majority of problems with software today… The primary status of complexity as the major cause comes simply from the fact that being able to understand a system is a prerequisite for avoiding all of them, and of course it is this which complexity destroys."

- Moseley & Marks

Page 10: Strategies for Mitigating Complexity in React Based Redux Applicaitons

COMPLEX SIMPLE

Stateful components. Stateless components.

Too many props. Use Redux containers liberally.

Conditional statements in reducers. Normalize at boundaries.

Scattered with side-effects. Side-effects at one point in the update loop.

Page 11: Strategies for Mitigating Complexity in React Based Redux Applicaitons

COMPLEX SIMPLE

Stateful components. Stateless components.

Too many props. Use Redux containers liberally.

Conditional statements in reducers. Normalize at boundaries.

Scattered with side-effects. Side-effects at one point in the update loop.

Page 12: Strategies for Mitigating Complexity in React Based Redux Applicaitons

COMPLEX SIMPLE

Stateful components. Stateless components.

Too many props. Use Redux containers liberally.

Conditional statements in reducers. Normalize at boundaries.

Scattered with side-effects. Side-effects at one point in the update loop.

Page 13: Strategies for Mitigating Complexity in React Based Redux Applicaitons

COMPLEX SIMPLE

Stateful components. Stateless components.

Too many props. Use Redux containers liberally.

Conditional statements in reducers. Normalize at boundaries.

Scattered with side-effects. Side-effects at one point in the update loop.

Page 14: Strategies for Mitigating Complexity in React Based Redux Applicaitons

COMPLEX SIMPLE

Stateful components. Stateless components.

Too many props. Use Redux containers liberally.

Conditional statements in reducers. Normalize at boundaries.

Scattered with side-effects. Side-effects at one point in the update loop.

Page 15: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Stateless components

Page 16: Strategies for Mitigating Complexity in React Based Redux Applicaitons

"The core premise for React is that UIs are simply a projection of data into a different form of data. The same input gives the same output."

- Sebastian Markbåge

Page 17: Strategies for Mitigating Complexity in React Based Redux Applicaitons

class Dropdown extends React.Component { constructor() { super();

this.state = {open: false}; this.handleToggle = () => { this.props.onToggle(); this.setState({open: !this.state.open}); } }

render() { const { options, selected, onSelect } = this.props;

const { open } = this.state;

// render some stuff }}

Page 18: Strategies for Mitigating Complexity in React Based Redux Applicaitons

class Dropdown extends React.Component { constructor() { super();

this.state = {open: false}; this.handleToggle = () => { this.props.onToggle(); this.setState({open: !this.state.open}); } }

render() { const { options, selected, onSelect } = this.props;

const { open } = this.state;

// render some stuff }}

Page 19: Strategies for Mitigating Complexity in React Based Redux Applicaitons

<Dropdown options={optionsA} selected={selectedA} onToggle={someFn} onSelect={someOtherFn}/>

<Dropdown options={optionsB} selected={selectedB} onToggle={someFn} onSelect={someOtherFn}/>

Page 20: Strategies for Mitigating Complexity in React Based Redux Applicaitons

<Dropdown options={optionsA} selected={selectedA} onToggle={someFn} onSelect={someOtherFn}+ open={open}/>

<Dropdown options={optionsB} selected={selectedB} onToggle={someFn} onSelect={someOtherFn}+ open={!open}/>

Page 21: Strategies for Mitigating Complexity in React Based Redux Applicaitons

class Dropdown extends React.Component {- constructor() {- super();-- this.state = {open: false};- this.handleToggle =- () => {- this.props.onToggle();- this.setState({open: !this.state.open});- }- }- render() { const { options, selected, onSelect,+ open,+ onToggle } = this.props;

- const {- open- } = this.state;

// render some stuff }}

Page 22: Strategies for Mitigating Complexity in React Based Redux Applicaitons

class StatefulDropdown extends React.Component { constructor() { super(); this.state = {open: false};

this.handleSelect = () => this.setState({open: !this.state.open}); }

render() { return ( <Dropdown options={this.props.options} selected={this.props.selected} open={this.state.open} onToggle={this.handleToggle} onSelect={this.props.onSelect} /> ); }}

Page 23: Strategies for Mitigating Complexity in React Based Redux Applicaitons

class StatefulDropdown extends React.Component { constructor() { super(); this.state = {open: false};

this.handleSelect = () => this.setState({open: !this.state.open}); }

render() { return ( <Dropdown options={this.props.options} selected={this.props.selected} open={this.state.open} onToggle={this.handleToggle} onSelect={this.props.onSelect} /> ); }}

Page 24: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Always keep lowest level components stateless

Keep them ALL stateless if you can

Switches can be flipped in a store and it Just Works™. More control.

You can always wrap a stateless component if you need stateful behavior.

Page 25: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Use Redux containers liberally

Page 26: Strategies for Mitigating Complexity in React Based Redux Applicaitons

function Targeting(props) { const { advancedTargetingAvailable, advancedTargetingEnabled, advancedTargetingExpanded, cookieTargetingEnabled, domain, hideRules, urlTargets, onRuleChangeAndSave, onRuleChange, onRemoveRule, onAddRule, onDomainChange, frequency, cookieTarget, geoTargets, referrerTargets, onChangeFrequency, onBlurFrequency, onChangeCookieType, onBlurCookieName, onChangeCookieName, onExpandAdvancedTargeting, onToggleGeoTargetsEnabled, onToggleReferrerTargetsEnabled, onChangeGeoTargets, planUpgradeLink, firstName,

Page 27: Strategies for Mitigating Complexity in React Based Redux Applicaitons

function Targeting(props) { const { domain, advancedTargetingAvailable } = props;

return ( <div> <div> Domain: {domain} Pro Account? {advancedTargetingAvailable} </div> <FrequencyContainer /> <GeoContainer /> <ReferrerContainer /> </div> );}

Page 28: Strategies for Mitigating Complexity in React Based Redux Applicaitons

<Provider store={store}> <TargetingContainer /></Provider>

<Provider store={store}> <FrequencyContainer /></Provider>

Page 29: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Low cost for huge readability win (components only require what they need).

Depending on hierarchy it may be a perf win.

Page 30: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Normalize at boundaries.

Page 31: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Red

Green

Blue

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }};

const state = { backgroundColor: 'white'};

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 32: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Red

Green

Blue

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }};

const state = { backgroundColor: 'white'};

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 33: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Red

Green

Blue

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }};

const state = { backgroundColor: 'white'};

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 34: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Red

Green

Blue

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }};

const state = { backgroundColor: 'white'};

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 35: Strategies for Mitigating Complexity in React Based Redux Applicaitons

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }}

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }};

const state = { backgroundColor: 'white'};

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 36: Strategies for Mitigating Complexity in React Based Redux Applicaitons

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }}

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }};

const state = { backgroundColor: 'white'};

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 37: Strategies for Mitigating Complexity in React Based Redux Applicaitons

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }}

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }};

const state = { backgroundColor: 'white'};

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 38: Strategies for Mitigating Complexity in React Based Redux Applicaitons

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }}

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }};

const state = { backgroundColor: 'white'};

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 39: Strategies for Mitigating Complexity in React Based Redux Applicaitons

const initialState = { backgroundColor: 'white'};

function reducer(state, action) { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; default: return state; }};

const AppContainer = connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => dispatch({type: 'CHANGE_COLOR', color}) }))(App);

Page 40: Strategies for Mitigating Complexity in React Based Redux Applicaitons

const initialState = { backgroundColor: 'white'};

function reducer(state, action) { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; default: return state; }};

const AppContainer = connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => dispatch({type: 'CHANGE_COLOR', color}) }))(App);

Page 41: Strategies for Mitigating Complexity in React Based Redux Applicaitons

const initialState = { backgroundColor: 'white'};

function reducer(state, action) { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; default: return state; }};

const AppContainer = connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => dispatch({type: 'CHANGE_COLOR', color}) }))(App);

Page 42: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Requirements change!

Page 43: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Red

Green

Blue

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }};

const state = { backgroundColor: 'white'};

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 44: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Red

Green

Blue

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }

const state = { backgroundColor: 'white'

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 45: Strategies for Mitigating Complexity in React Based Redux Applicaitons

const initialState = { backgroundColor: 'white',+ borderColor: null};

class App extends React.Component { render() { const { backgroundColor, onClick,+ borderColor } = this.props;

+ const border = borderColor ? `35px solid ${borderColor}` : null;+ return (- <div style={{backgroundColor}}>+ <div style={{backgroundColor, border}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }}

Page 46: Strategies for Mitigating Complexity in React Based Redux Applicaitons

const initialState = { backgroundColor: 'white',+ borderColor: null};

class App extends React.Component { render() { const { backgroundColor, onClick,+ borderColor } = this.props;

+ const border = borderColor ? `35px solid ${borderColor}` : null;+ return (- <div style={{backgroundColor}}>+ <div style={{backgroundColor, border}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }}

Page 47: Strategies for Mitigating Complexity in React Based Redux Applicaitons

function reducer(state, action) { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color,+ borderColor: action.color === 'red' ? 'purple' : null }; default: return state; }};

Page 48: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Requirements change!

Page 49: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Red

Green

Blue

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }};

const state = { backgroundColor: 'white'};

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 50: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Red

Green

Blue

class App extends React.Component { render() { const { backgroundColor, onClick } = this.props;

return ( <div style={{backgroundColor}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }

(state, action) => { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color }; }};

const state = { backgroundColor: 'white'};

connect( // mapStateToProps state => state,

// mapDispatchToProps dispatch => ({ onClick: color => {type: 'CHANGE_COLOR', color} }))(App);

Page 51: Strategies for Mitigating Complexity in React Based Redux Applicaitons

const initialState = { backgroundColor: 'white', borderColor: null,+ width: '100%'};

class App extends React.Component { render() { const { backgroundColor, onClick, borderColor,+ width } = this.props;

const border = borderColor ? `35px solid ${borderColor}` : null;

return (- <div style={{backgroundColor, border}}>+ <div style={{backgroundColor, border, width}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }}

Page 52: Strategies for Mitigating Complexity in React Based Redux Applicaitons

const initialState = { backgroundColor: 'white', borderColor: null,+ width: '100%'};

class App extends React.Component { render() { const { backgroundColor, onClick, borderColor,+ width } = this.props;

const border = borderColor ? `35px solid ${borderColor}` : null;

return (- <div style={{backgroundColor, border}}>+ <div style={{backgroundColor, border, width}}> <button onClick={() => onClick('red')}> Red </button> <button onClick={() => onClick('green')}> Green </button> <button onClick={() => onClick('red')}> Blue </button> </div> ) }}

Page 53: Strategies for Mitigating Complexity in React Based Redux Applicaitons

function reducer(state, action) { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color, borderColor: action.color === 'red' ? 'purple' : null,+ width: action.color === 'green' ? '50%' : '100%' }; default: return state; }};

Page 54: Strategies for Mitigating Complexity in React Based Redux Applicaitons

function reducer(state, action) { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color, borderColor: action.color === 'red' ? 'purple' : null,+ borderRadius: action.color === 'blue' ? '50%' : 0, width: action.color === 'green' ? '50%' : '100%', }; default: return state; }};

Page 55: Strategies for Mitigating Complexity in React Based Redux Applicaitons

function reducer(state, action) { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color,- borderColor: action.color === 'red' ? 'purple' : null,+ borderColor: action.color === 'red' || action.color === 'yellow' ? 'purple' : null,- borderRadius: action.color === 'blue' ? '50%' : 0,+ borderRadius: action.color === 'blue' || action.color === 'yellow' ? '50%' : 0,- width: action.color === 'green' ? '50%' : '100%',+ width: action.color === 'green' || action.color === 'yellow' ? '50%' : '100%', }; default: return state; }};

Page 56: Strategies for Mitigating Complexity in React Based Redux Applicaitons

function reducer(state, action) { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color, borderColor: action.color === 'red' || action.color === 'yellow' ? 'purple' : null, borderRadius: action.color === 'blue' || action.color === 'yellow' ? '50%' : 0, width: action.color === 'green' || action.color === 'yellow' ? '50%' : '100%', }; default: return state; }};

Page 57: Strategies for Mitigating Complexity in React Based Redux Applicaitons

function reducer(state, action) { switch (action.type) { case 'CHOOSE_RED': return { ...state, backgroundColor: 'red', borderColor: 'purple', borderRadius: 0, width: '100%' }; case 'CHOOSE_BLUE': return { ...state, backgroundColor: 'blue', borderColor: null, borderRadius: '50%', width: '100%' }; case 'CHOOSE_GREEN': return { ...state, backgroundColor: 'green', borderColor: null, borderRadius: 0, width: '50%' }; case 'CHOOSE_YELLOW': return { ...state, backgroundColor: 'yellow', borderColor: 'purple', borderRadius: '50%', width: '50%' }; default: return state; }};

Page 58: Strategies for Mitigating Complexity in React Based Redux Applicaitons

class App extends React.Component { render() { const { backgroundColor, onClickRed, onClickGreen, onClickBlue, onClickYellow borderColor, width } = this.props;

const border = borderColor ? `35px solid ${borderColor}` : null;

return ( <div style={{backgroundColor, border, width}}> <button onClick={() => onClickRed()}> Red </button> <button onClick={() => onClickGreen()}> Green </button> <button onClick={() => onClickBlue()}> Blue </button> <button onClick={() => onClickYellow()}> Yellow </button> </div> ) }}

Page 59: Strategies for Mitigating Complexity in React Based Redux Applicaitons

class App extends React.Component { render() { const { backgroundColor, onClickRed, onClickGreen, onClickBlue, onClickYellow borderColor, width } = this.props;

const border = borderColor ? `35px solid ${borderColor}` : null;

return ( <div style={{backgroundColor, border, width}}> <button onClick={() => onClickRed()}> Red </button> <button onClick={() => onClickGreen()}> Green </button> <button onClick={() => onClickBlue()}> Blue </button> <button onClick={() => onClickYellow()}> Yellow </button> </div> ) }}

Page 60: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Boilerplate (more actions, larger reducers).

Code is easier to remove if it is no longer required.

Fewer code paths.

Easier to type check if you're into that.

Page 61: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Side-effects at one point in the update loop.

Page 62: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Action Dispatcher Store View

Action

Async

Page 63: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Action Dispatcher Store

View

Action

Async

Page 64: Strategies for Mitigating Complexity in React Based Redux Applicaitons

Action Dispatcher Store

View

Action

?

Page 65: Strategies for Mitigating Complexity in React Based Redux Applicaitons

const initialState = { user: { id: 1, name: 'Bob' }, busyState: 'READY'};

function reducer(state, action) { switch (action.type) { case 'SAVING_USER': return { ...state, busyState: 'SAVING' }; case 'SAVING_USER_COMPLETE': return { ...state, busyState: 'READY' }; default: return state; }}

let watch = watcher();

watch = applyHandler( watch, ['busyState', 'user.name'], ([busyState, name]) => busyState === 'SAVING' && name.length > 0 updateUser, store => store.dispatch(savingUserComplete()));

const store = createStore(reducer, initialState, watch);

Page 66: Strategies for Mitigating Complexity in React Based Redux Applicaitons

const initialState = { user: { id: 1, name: 'Bob' }, busyState: 'READY'};

function reducer(state, action) { switch (action.type) { case 'SAVING_USER': return { ...state, busyState: 'SAVING' }; case 'SAVING_USER_COMPLETE': return { ...state, busyState: 'READY' }; default: return state; }}

let watch = watcher();

watch = applyHandler( watch, ['busyState', 'user.name'], ([busyState, name]) => busyState === 'SAVING' && name.length > 0 updateUser, store => store.dispatch(savingUserComplete()));

const store = createStore(reducer, initialState, watch);

Page 67: Strategies for Mitigating Complexity in React Based Redux Applicaitons

const initialState = { user: { id: 1, name: 'Bob' }, busyState: 'READY'};

function reducer(state, action) { switch (action.type) { case 'SAVING_USER': return { ...state, busyState: 'SAVING' }; case 'SAVING_USER_COMPLETE': return { ...state, busyState: 'READY' }; default: return state; }}

let watch = watcher();

watch = applyHandler( watch, ['busyState', 'user.name'], ([busyState, name]) => busyState === 'SAVING' && name.length > 0 updateUser, store => store.dispatch(savingUserComplete()));

const store = createStore(reducer, initialState, watch);

Page 68: Strategies for Mitigating Complexity in React Based Redux Applicaitons

const initialState = { user: { id: 1, name: 'Bob' }, busyState: 'READY'};

function reducer(state, action) { switch (action.type) { case 'SAVING_USER': return { ...state, busyState: 'SAVING' }; case 'SAVING_USER_COMPLETE': return { ...state, busyState: 'READY' }; default: return state; }}

let watch = watcher();

watch = applyHandler( watch, ['busyState', 'user.name'], ([busyState, name]) => busyState === 'SAVING' && name.length > 0 updateUser, store => store.dispatch(savingUserComplete()));

const store = createStore(reducer, initialState, watch);

Page 69: Strategies for Mitigating Complexity in React Based Redux Applicaitons

All actions are synchronous.

Async is represented in state by default.

All side-effects occur at the end of the update loop.

Easier to substitute based on the context.

Page 70: Strategies for Mitigating Complexity in React Based Redux Applicaitons

COMPLEX SIMPLE

Stateful components. Stateless components.

Too many props. Use Redux containers liberally.

Conditional statements in reducers. Normalize at boundaries.

Scattered with side-effects. Side-effects at one point in the update loop.

Page 71: Strategies for Mitigating Complexity in React Based Redux Applicaitons

THANKS!

https://www.infoq.com/presentations/Simple-Made-Easy

http://shaffner.us/cs/papers/tarpit.pdf

https://github.com/reactjs/react-basic