SlideShare a Scribd company logo
HELLO,
REACT.JS VANCOUVER!
Me
gabe.scholz@unbounce.com
https://github.com/garbles
Strategies for Mitigating Complexity in React Based Redux Applicaitons
Strategies for Mitigating
Complexity in React
Based Redux Applications
Designing for Simplicity
"The computing scientist’s main
challenge is not to get confused by
the complexities of his own making."
- E. W. Dijkstra
"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)
Tests
"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
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.
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.
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.
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.
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.
Stateless components
"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
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
}
}
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
}
}
<Dropdown
options={optionsA}
selected={selectedA}
onToggle={someFn}
onSelect={someOtherFn}
/>
<Dropdown
options={optionsB}
selected={selectedB}
onToggle={someFn}
onSelect={someOtherFn}
/>
<Dropdown
options={optionsA}
selected={selectedA}
onToggle={someFn}
onSelect={someOtherFn}
+ open={open}
/>
<Dropdown
options={optionsB}
selected={selectedB}
onToggle={someFn}
onSelect={someOtherFn}
+ open={!open}
/>
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
}
}
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}
/>
);
}
}
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}
/>
);
}
}
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.
Use Redux containers
liberally
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,
function Targeting(props) {
const {
domain,
advancedTargetingAvailable
} = props;
return (
<div>
<div>
Domain: {domain}
Pro Account? {advancedTargetingAvailable}
</div>
<FrequencyContainer />
<GeoContainer />
<ReferrerContainer />
</div>
);
}
<Provider store={store}>
<TargetingContainer />
</Provider>
<Provider store={store}>
<FrequencyContainer />
</Provider>
Low cost for huge readability win (components
only require what they need).
Depending on hierarchy it may be a perf win.
Normalize at
boundaries.
Red
Green
Blue
Red
Green
Blue
Red
Green
Blue
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>
)
}
}
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>
)
}
}
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>
)
}
}
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>
)
}
}
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);
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);
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);
Requirements change!
Red
Green
Blue
Red
Green
Blue
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>
)
}
}
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>
)
}
}
function reducer(state, action) {
switch (action.type) {
case 'CHANGE_COLOR':
return {
...state,
backgroundColor: action.color,
+ borderColor: action.color === 'red' ? 'purple' : null
};
default:
return state;
}
};
Requirements change!
Red
Green
Blue
Red
Green
Blue
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>
)
}
}
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>
)
}
}
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;
}
};
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;
}
};
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;
}
};
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;
}
};
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;
}
};
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>
)
}
}
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>
)
}
}
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.
Side-effects at one point
in the update loop.
Action Dispatcher Store View
Action
Async
Action Dispatcher Store
View
Action
Async
Action Dispatcher Store
View
Action
?
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);
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);
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);
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);
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.
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.
THANKS!
https://www.infoq.com/presentations/Simple-Made-Easy
http://shaffner.us/cs/papers/tarpit.pdf
https://github.com/reactjs/react-basic

More Related Content

What's hot (20)

Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
Droidcon Berlin
 
Magento Dependency Injection
Magento Dependency InjectionMagento Dependency Injection
Magento Dependency Injection
Anton Kril
 
Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1
Augustin Bralley
 
Android 3
Android 3Android 3
Android 3
Robert Cooper
 
Handling action bar in Android
Handling action bar in AndroidHandling action bar in Android
Handling action bar in Android
indiangarg
 
Quick Intro to Android Development
Quick Intro to Android DevelopmentQuick Intro to Android Development
Quick Intro to Android Development
Jussi Pohjolainen
 
Deep Dive into React Hooks
Deep Dive into React HooksDeep Dive into React Hooks
Deep Dive into React Hooks
Felix Kühl
 
BVJS
BVJSBVJS
BVJS
Rebecca Murphey
 
culadora cientifica en java
culadora cientifica en javaculadora cientifica en java
culadora cientifica en java
Jorge Llocclla Rojas
 
Ip project
Ip projectIp project
Ip project
Anurag Surya
 
State of the state
State of the stateState of the state
State of the state
Anton Korzunov
 
MVI - Managing State The Kotlin Way
MVI - Managing State The Kotlin WayMVI - Managing State The Kotlin Way
MVI - Managing State The Kotlin Way
Zeyad Gasser
 
Delivering a Responsive UI
Delivering a Responsive UIDelivering a Responsive UI
Delivering a Responsive UI
Rebecca Murphey
 
Android Testing
Android TestingAndroid Testing
Android Testing
Evan Lin
 
A comprehensive guide on developing responsive and common react filter component
A comprehensive guide on developing responsive and common react filter componentA comprehensive guide on developing responsive and common react filter component
A comprehensive guide on developing responsive and common react filter component
Katy Slemon
 
jrubykaigi2010-lt-rubeus
jrubykaigi2010-lt-rubeusjrubykaigi2010-lt-rubeus
jrubykaigi2010-lt-rubeus
Takeshi AKIMA
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
Артём Курапов
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
Eric Maxwell
 
Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1
Kevin Octavian
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Events
dmethvin
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
Droidcon Berlin
 
Magento Dependency Injection
Magento Dependency InjectionMagento Dependency Injection
Magento Dependency Injection
Anton Kril
 
Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1
Augustin Bralley
 
Handling action bar in Android
Handling action bar in AndroidHandling action bar in Android
Handling action bar in Android
indiangarg
 
Quick Intro to Android Development
Quick Intro to Android DevelopmentQuick Intro to Android Development
Quick Intro to Android Development
Jussi Pohjolainen
 
Deep Dive into React Hooks
Deep Dive into React HooksDeep Dive into React Hooks
Deep Dive into React Hooks
Felix Kühl
 
MVI - Managing State The Kotlin Way
MVI - Managing State The Kotlin WayMVI - Managing State The Kotlin Way
MVI - Managing State The Kotlin Way
Zeyad Gasser
 
Delivering a Responsive UI
Delivering a Responsive UIDelivering a Responsive UI
Delivering a Responsive UI
Rebecca Murphey
 
Android Testing
Android TestingAndroid Testing
Android Testing
Evan Lin
 
A comprehensive guide on developing responsive and common react filter component
A comprehensive guide on developing responsive and common react filter componentA comprehensive guide on developing responsive and common react filter component
A comprehensive guide on developing responsive and common react filter component
Katy Slemon
 
jrubykaigi2010-lt-rubeus
jrubykaigi2010-lt-rubeusjrubykaigi2010-lt-rubeus
jrubykaigi2010-lt-rubeus
Takeshi AKIMA
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
Eric Maxwell
 
Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1
Kevin Octavian
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Events
dmethvin
 

Viewers also liked (17)

Students co creating course content and evaluating their own learning
Students co creating course content and evaluating their own learningStudents co creating course content and evaluating their own learning
Students co creating course content and evaluating their own learning
Michael Paskevicius
 
The Fourth Screen v4.2
The Fourth Screen v4.2The Fourth Screen v4.2
The Fourth Screen v4.2
Darren Kuropatwa
 
Esos Raros Lenguajes Nuevos
Esos Raros Lenguajes NuevosEsos Raros Lenguajes Nuevos
Esos Raros Lenguajes Nuevos
Eduardo Diaz
 
Making Student Thinking Visible v4
 Making Student Thinking Visible v4 Making Student Thinking Visible v4
Making Student Thinking Visible v4
Darren Kuropatwa
 
Tales of Learning and the Gifts of Footprints v4.2
Tales of Learning and the Gifts of Footprints v4.2Tales of Learning and the Gifts of Footprints v4.2
Tales of Learning and the Gifts of Footprints v4.2
Darren Kuropatwa
 
Lemoine brandon ppp
Lemoine brandon pppLemoine brandon ppp
Lemoine brandon ppp
Brandon Lemoine
 
Distribucion normal, binomial y poisson
Distribucion normal, binomial y poisson Distribucion normal, binomial y poisson
Distribucion normal, binomial y poisson
Jessenia Alacayo
 
Taller 1. conflicto armado chcv (3)
Taller 1. conflicto armado chcv (3)Taller 1. conflicto armado chcv (3)
Taller 1. conflicto armado chcv (3)
Jorge Reyes
 
III ciclo unidad_de_estadistica
III ciclo unidad_de_estadisticaIII ciclo unidad_de_estadistica
III ciclo unidad_de_estadistica
Johanna Mena González
 
III ciclo unidad_de_probabilidad
III ciclo unidad_de_probabilidadIII ciclo unidad_de_probabilidad
III ciclo unidad_de_probabilidad
Johanna Mena González
 
KBM_WomenInBusinessAwards
KBM_WomenInBusinessAwardsKBM_WomenInBusinessAwards
KBM_WomenInBusinessAwards
Audrey Repin
 
Voz pasiva y voz activa
Voz pasiva y voz activaVoz pasiva y voz activa
Voz pasiva y voz activa
WuendyFer2405
 
LEG.2016.Wins
LEG.2016.WinsLEG.2016.Wins
LEG.2016.Wins
Catherine Lew, Esq.
 
Actividad2 m1 calc_bas (3)
Actividad2 m1 calc_bas (3)Actividad2 m1 calc_bas (3)
Actividad2 m1 calc_bas (3)
miguelanyeka
 
Manual de Gerador de Calor para Sauna Seca Sodramar
Manual de Gerador de Calor para Sauna Seca SodramarManual de Gerador de Calor para Sauna Seca Sodramar
Manual de Gerador de Calor para Sauna Seca Sodramar
Cottage Casa E Lazer
 
Gdz ros mova_rydyakov_2014
Gdz ros mova_rydyakov_2014Gdz ros mova_rydyakov_2014
Gdz ros mova_rydyakov_2014
Lucky Alex
 
The Spine and Its Vulnerability to Disc Rupture and Herniation
The Spine and Its Vulnerability to Disc Rupture and HerniationThe Spine and Its Vulnerability to Disc Rupture and Herniation
The Spine and Its Vulnerability to Disc Rupture and Herniation
Dr. Donald R. DeFeo
 
Students co creating course content and evaluating their own learning
Students co creating course content and evaluating their own learningStudents co creating course content and evaluating their own learning
Students co creating course content and evaluating their own learning
Michael Paskevicius
 
Esos Raros Lenguajes Nuevos
Esos Raros Lenguajes NuevosEsos Raros Lenguajes Nuevos
Esos Raros Lenguajes Nuevos
Eduardo Diaz
 
Making Student Thinking Visible v4
 Making Student Thinking Visible v4 Making Student Thinking Visible v4
Making Student Thinking Visible v4
Darren Kuropatwa
 
Tales of Learning and the Gifts of Footprints v4.2
Tales of Learning and the Gifts of Footprints v4.2Tales of Learning and the Gifts of Footprints v4.2
Tales of Learning and the Gifts of Footprints v4.2
Darren Kuropatwa
 
Distribucion normal, binomial y poisson
Distribucion normal, binomial y poisson Distribucion normal, binomial y poisson
Distribucion normal, binomial y poisson
Jessenia Alacayo
 
Taller 1. conflicto armado chcv (3)
Taller 1. conflicto armado chcv (3)Taller 1. conflicto armado chcv (3)
Taller 1. conflicto armado chcv (3)
Jorge Reyes
 
KBM_WomenInBusinessAwards
KBM_WomenInBusinessAwardsKBM_WomenInBusinessAwards
KBM_WomenInBusinessAwards
Audrey Repin
 
Voz pasiva y voz activa
Voz pasiva y voz activaVoz pasiva y voz activa
Voz pasiva y voz activa
WuendyFer2405
 
Actividad2 m1 calc_bas (3)
Actividad2 m1 calc_bas (3)Actividad2 m1 calc_bas (3)
Actividad2 m1 calc_bas (3)
miguelanyeka
 
Manual de Gerador de Calor para Sauna Seca Sodramar
Manual de Gerador de Calor para Sauna Seca SodramarManual de Gerador de Calor para Sauna Seca Sodramar
Manual de Gerador de Calor para Sauna Seca Sodramar
Cottage Casa E Lazer
 
Gdz ros mova_rydyakov_2014
Gdz ros mova_rydyakov_2014Gdz ros mova_rydyakov_2014
Gdz ros mova_rydyakov_2014
Lucky Alex
 
The Spine and Its Vulnerability to Disc Rupture and Herniation
The Spine and Its Vulnerability to Disc Rupture and HerniationThe Spine and Its Vulnerability to Disc Rupture and Herniation
The Spine and Its Vulnerability to Disc Rupture and Herniation
Dr. Donald R. DeFeo
 

Similar to Strategies for Mitigating Complexity in React Based Redux Applicaitons (20)

Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
Ignacio Martín
 
React + Redux. Best practices
React + Redux.  Best practicesReact + Redux.  Best practices
React + Redux. Best practices
Clickky
 
React redux
React reduxReact redux
React redux
Michel Perez
 
Recompacting your react application
Recompacting your react applicationRecompacting your react application
Recompacting your react application
Greg Bergé
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
Ignacio Martín
 
Spin Up Desktop Apps with Electron.js
Spin Up Desktop Apps with Electron.jsSpin Up Desktop Apps with Electron.js
Spin Up Desktop Apps with Electron.js
Steve Godin
 
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JSFestUA
 
React hooks
React hooksReact hooks
React hooks
Assaf Gannon
 
N Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React NativeN Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React Native
Anton Kulyk
 
Ngrx slides
Ngrx slidesNgrx slides
Ngrx slides
Christoffer Noring
 
React 101
React 101React 101
React 101
Casear Chu
 
React JS Hooks Sheet .pdf
React JS Hooks Sheet .pdfReact JS Hooks Sheet .pdf
React JS Hooks Sheet .pdf
nishant078cs23
 
React lecture
React lectureReact lecture
React lecture
Christoffer Noring
 
React new features and intro to Hooks
React new features and intro to HooksReact new features and intro to Hooks
React new features and intro to Hooks
Soluto
 
Reactивная тяга
Reactивная тягаReactивная тяга
Reactивная тяга
Vitebsk Miniq
 
How Reactive do we need to be
How Reactive do we need to beHow Reactive do we need to be
How Reactive do we need to be
Jana Karceska
 
Higher-Order Components — Ilya Gelman
Higher-Order Components — Ilya GelmanHigher-Order Components — Ilya Gelman
Higher-Order Components — Ilya Gelman
500Tech
 
ReactJS
ReactJSReactJS
ReactJS
Kamlesh Singh
 
React, Redux and es6/7
React, Redux and es6/7React, Redux and es6/7
React, Redux and es6/7
Dongho Cho
 
How do we use hooks
How do we use hooksHow do we use hooks
How do we use hooks
Jim Liu
 
React + Redux. Best practices
React + Redux.  Best practicesReact + Redux.  Best practices
React + Redux. Best practices
Clickky
 
Recompacting your react application
Recompacting your react applicationRecompacting your react application
Recompacting your react application
Greg Bergé
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
Ignacio Martín
 
Spin Up Desktop Apps with Electron.js
Spin Up Desktop Apps with Electron.jsSpin Up Desktop Apps with Electron.js
Spin Up Desktop Apps with Electron.js
Steve Godin
 
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JSFestUA
 
N Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React NativeN Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React Native
Anton Kulyk
 
React JS Hooks Sheet .pdf
React JS Hooks Sheet .pdfReact JS Hooks Sheet .pdf
React JS Hooks Sheet .pdf
nishant078cs23
 
React new features and intro to Hooks
React new features and intro to HooksReact new features and intro to Hooks
React new features and intro to Hooks
Soluto
 
Reactивная тяга
Reactивная тягаReactивная тяга
Reactивная тяга
Vitebsk Miniq
 
How Reactive do we need to be
How Reactive do we need to beHow Reactive do we need to be
How Reactive do we need to be
Jana Karceska
 
Higher-Order Components — Ilya Gelman
Higher-Order Components — Ilya GelmanHigher-Order Components — Ilya Gelman
Higher-Order Components — Ilya Gelman
500Tech
 
React, Redux and es6/7
React, Redux and es6/7React, Redux and es6/7
React, Redux and es6/7
Dongho Cho
 
How do we use hooks
How do we use hooksHow do we use hooks
How do we use hooks
Jim Liu
 

Recently uploaded (20)

ADVXAI IN MALWARE ANALYSIS FRAMEWORK: BALANCING EXPLAINABILITY WITH SECURITY
ADVXAI IN MALWARE ANALYSIS FRAMEWORK: BALANCING EXPLAINABILITY WITH SECURITYADVXAI IN MALWARE ANALYSIS FRAMEWORK: BALANCING EXPLAINABILITY WITH SECURITY
ADVXAI IN MALWARE ANALYSIS FRAMEWORK: BALANCING EXPLAINABILITY WITH SECURITY
ijscai
 
Introduction to FLUID MECHANICS & KINEMATICS
Introduction to FLUID MECHANICS &  KINEMATICSIntroduction to FLUID MECHANICS &  KINEMATICS
Introduction to FLUID MECHANICS & KINEMATICS
narayanaswamygdas
 
"Feed Water Heaters in Thermal Power Plants: Types, Working, and Efficiency G...
"Feed Water Heaters in Thermal Power Plants: Types, Working, and Efficiency G..."Feed Water Heaters in Thermal Power Plants: Types, Working, and Efficiency G...
"Feed Water Heaters in Thermal Power Plants: Types, Working, and Efficiency G...
Infopitaara
 
Smart_Storage_Systems_Production_Engineering.pptx
Smart_Storage_Systems_Production_Engineering.pptxSmart_Storage_Systems_Production_Engineering.pptx
Smart_Storage_Systems_Production_Engineering.pptx
rushikeshnavghare94
 
DATA-DRIVEN SHOULDER INVERSE KINEMATICS YoungBeom Kim1 , Byung-Ha Park1 , Kwa...
DATA-DRIVEN SHOULDER INVERSE KINEMATICS YoungBeom Kim1 , Byung-Ha Park1 , Kwa...DATA-DRIVEN SHOULDER INVERSE KINEMATICS YoungBeom Kim1 , Byung-Ha Park1 , Kwa...
DATA-DRIVEN SHOULDER INVERSE KINEMATICS YoungBeom Kim1 , Byung-Ha Park1 , Kwa...
charlesdick1345
 
Process Parameter Optimization for Minimizing Springback in Cold Drawing Proc...
Process Parameter Optimization for Minimizing Springback in Cold Drawing Proc...Process Parameter Optimization for Minimizing Springback in Cold Drawing Proc...
Process Parameter Optimization for Minimizing Springback in Cold Drawing Proc...
Journal of Soft Computing in Civil Engineering
 
Level 1-Safety.pptx Presentation of Electrical Safety
Level 1-Safety.pptx Presentation of Electrical SafetyLevel 1-Safety.pptx Presentation of Electrical Safety
Level 1-Safety.pptx Presentation of Electrical Safety
JoseAlbertoCariasDel
 
Machine learning project on employee attrition detection using (2).pptx
Machine learning project on employee attrition detection using (2).pptxMachine learning project on employee attrition detection using (2).pptx
Machine learning project on employee attrition detection using (2).pptx
rajeswari89780
 
Raish Khanji GTU 8th sem Internship Report.pdf
Raish Khanji GTU 8th sem Internship Report.pdfRaish Khanji GTU 8th sem Internship Report.pdf
Raish Khanji GTU 8th sem Internship Report.pdf
RaishKhanji
 
IntroSlides-April-BuildWithAI-VertexAI.pdf
IntroSlides-April-BuildWithAI-VertexAI.pdfIntroSlides-April-BuildWithAI-VertexAI.pdf
IntroSlides-April-BuildWithAI-VertexAI.pdf
Luiz Carneiro
 
Smart Storage Solutions.pptx for production engineering
Smart Storage Solutions.pptx for production engineeringSmart Storage Solutions.pptx for production engineering
Smart Storage Solutions.pptx for production engineering
rushikeshnavghare94
 
LECTURE-16 EARTHEN DAM - II.pptx it's uses
LECTURE-16 EARTHEN DAM - II.pptx it's usesLECTURE-16 EARTHEN DAM - II.pptx it's uses
LECTURE-16 EARTHEN DAM - II.pptx it's uses
CLokeshBehera123
 
MAQUINARIA MINAS CEMA 6th Edition (1).pdf
MAQUINARIA MINAS CEMA 6th Edition (1).pdfMAQUINARIA MINAS CEMA 6th Edition (1).pdf
MAQUINARIA MINAS CEMA 6th Edition (1).pdf
ssuser562df4
 
DSP and MV the Color image processing.ppt
DSP and MV the  Color image processing.pptDSP and MV the  Color image processing.ppt
DSP and MV the Color image processing.ppt
HafizAhamed8
 
new ppt artificial intelligence historyyy
new ppt artificial intelligence historyyynew ppt artificial intelligence historyyy
new ppt artificial intelligence historyyy
PianoPianist
 
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptxExplainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
MahaveerVPandit
 
some basics electrical and electronics knowledge
some basics electrical and electronics knowledgesome basics electrical and electronics knowledge
some basics electrical and electronics knowledge
nguyentrungdo88
 
Metal alkyne complexes.pptx in chemistry
Metal alkyne complexes.pptx in chemistryMetal alkyne complexes.pptx in chemistry
Metal alkyne complexes.pptx in chemistry
mee23nu
 
Oil-gas_Unconventional oil and gass_reseviours.pdf
Oil-gas_Unconventional oil and gass_reseviours.pdfOil-gas_Unconventional oil and gass_reseviours.pdf
Oil-gas_Unconventional oil and gass_reseviours.pdf
M7md3li2
 
fluke dealers in bangalore..............
fluke dealers in bangalore..............fluke dealers in bangalore..............
fluke dealers in bangalore..............
Haresh Vaswani
 
ADVXAI IN MALWARE ANALYSIS FRAMEWORK: BALANCING EXPLAINABILITY WITH SECURITY
ADVXAI IN MALWARE ANALYSIS FRAMEWORK: BALANCING EXPLAINABILITY WITH SECURITYADVXAI IN MALWARE ANALYSIS FRAMEWORK: BALANCING EXPLAINABILITY WITH SECURITY
ADVXAI IN MALWARE ANALYSIS FRAMEWORK: BALANCING EXPLAINABILITY WITH SECURITY
ijscai
 
Introduction to FLUID MECHANICS & KINEMATICS
Introduction to FLUID MECHANICS &  KINEMATICSIntroduction to FLUID MECHANICS &  KINEMATICS
Introduction to FLUID MECHANICS & KINEMATICS
narayanaswamygdas
 
"Feed Water Heaters in Thermal Power Plants: Types, Working, and Efficiency G...
"Feed Water Heaters in Thermal Power Plants: Types, Working, and Efficiency G..."Feed Water Heaters in Thermal Power Plants: Types, Working, and Efficiency G...
"Feed Water Heaters in Thermal Power Plants: Types, Working, and Efficiency G...
Infopitaara
 
Smart_Storage_Systems_Production_Engineering.pptx
Smart_Storage_Systems_Production_Engineering.pptxSmart_Storage_Systems_Production_Engineering.pptx
Smart_Storage_Systems_Production_Engineering.pptx
rushikeshnavghare94
 
DATA-DRIVEN SHOULDER INVERSE KINEMATICS YoungBeom Kim1 , Byung-Ha Park1 , Kwa...
DATA-DRIVEN SHOULDER INVERSE KINEMATICS YoungBeom Kim1 , Byung-Ha Park1 , Kwa...DATA-DRIVEN SHOULDER INVERSE KINEMATICS YoungBeom Kim1 , Byung-Ha Park1 , Kwa...
DATA-DRIVEN SHOULDER INVERSE KINEMATICS YoungBeom Kim1 , Byung-Ha Park1 , Kwa...
charlesdick1345
 
Level 1-Safety.pptx Presentation of Electrical Safety
Level 1-Safety.pptx Presentation of Electrical SafetyLevel 1-Safety.pptx Presentation of Electrical Safety
Level 1-Safety.pptx Presentation of Electrical Safety
JoseAlbertoCariasDel
 
Machine learning project on employee attrition detection using (2).pptx
Machine learning project on employee attrition detection using (2).pptxMachine learning project on employee attrition detection using (2).pptx
Machine learning project on employee attrition detection using (2).pptx
rajeswari89780
 
Raish Khanji GTU 8th sem Internship Report.pdf
Raish Khanji GTU 8th sem Internship Report.pdfRaish Khanji GTU 8th sem Internship Report.pdf
Raish Khanji GTU 8th sem Internship Report.pdf
RaishKhanji
 
IntroSlides-April-BuildWithAI-VertexAI.pdf
IntroSlides-April-BuildWithAI-VertexAI.pdfIntroSlides-April-BuildWithAI-VertexAI.pdf
IntroSlides-April-BuildWithAI-VertexAI.pdf
Luiz Carneiro
 
Smart Storage Solutions.pptx for production engineering
Smart Storage Solutions.pptx for production engineeringSmart Storage Solutions.pptx for production engineering
Smart Storage Solutions.pptx for production engineering
rushikeshnavghare94
 
LECTURE-16 EARTHEN DAM - II.pptx it's uses
LECTURE-16 EARTHEN DAM - II.pptx it's usesLECTURE-16 EARTHEN DAM - II.pptx it's uses
LECTURE-16 EARTHEN DAM - II.pptx it's uses
CLokeshBehera123
 
MAQUINARIA MINAS CEMA 6th Edition (1).pdf
MAQUINARIA MINAS CEMA 6th Edition (1).pdfMAQUINARIA MINAS CEMA 6th Edition (1).pdf
MAQUINARIA MINAS CEMA 6th Edition (1).pdf
ssuser562df4
 
DSP and MV the Color image processing.ppt
DSP and MV the  Color image processing.pptDSP and MV the  Color image processing.ppt
DSP and MV the Color image processing.ppt
HafizAhamed8
 
new ppt artificial intelligence historyyy
new ppt artificial intelligence historyyynew ppt artificial intelligence historyyy
new ppt artificial intelligence historyyy
PianoPianist
 
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptxExplainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
MahaveerVPandit
 
some basics electrical and electronics knowledge
some basics electrical and electronics knowledgesome basics electrical and electronics knowledge
some basics electrical and electronics knowledge
nguyentrungdo88
 
Metal alkyne complexes.pptx in chemistry
Metal alkyne complexes.pptx in chemistryMetal alkyne complexes.pptx in chemistry
Metal alkyne complexes.pptx in chemistry
mee23nu
 
Oil-gas_Unconventional oil and gass_reseviours.pdf
Oil-gas_Unconventional oil and gass_reseviours.pdfOil-gas_Unconventional oil and gass_reseviours.pdf
Oil-gas_Unconventional oil and gass_reseviours.pdf
M7md3li2
 
fluke dealers in bangalore..............
fluke dealers in bangalore..............fluke dealers in bangalore..............
fluke dealers in bangalore..............
Haresh Vaswani
 

Strategies for Mitigating Complexity in React Based Redux Applicaitons

  • 4. Strategies for Mitigating Complexity in React Based Redux Applications
  • 6. "The computing scientist’s main challenge is not to get confused by the complexities of his own making." - E. W. Dijkstra
  • 7. "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)
  • 9. "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
  • 10. 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.
  • 11. 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.
  • 12. 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.
  • 13. 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.
  • 14. 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.
  • 16. "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
  • 17. 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 } }
  • 18. 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 } }
  • 21. 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 } }
  • 22. 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} /> ); } }
  • 23. 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} /> ); } }
  • 24. 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.
  • 26. 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,
  • 27. function Targeting(props) { const { domain, advancedTargetingAvailable } = props; return ( <div> <div> Domain: {domain} Pro Account? {advancedTargetingAvailable} </div> <FrequencyContainer /> <GeoContainer /> <ReferrerContainer /> </div> ); }
  • 28. <Provider store={store}> <TargetingContainer /> </Provider> <Provider store={store}> <FrequencyContainer /> </Provider>
  • 29. Low cost for huge readability win (components only require what they need). Depending on hierarchy it may be a perf win.
  • 35. 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> ) } }
  • 36. 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> ) } }
  • 37. 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> ) } }
  • 38. 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> ) } }
  • 39. 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);
  • 40. 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);
  • 41. 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);
  • 45. 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> ) } }
  • 46. 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> ) } }
  • 47. function reducer(state, action) { switch (action.type) { case 'CHANGE_COLOR': return { ...state, backgroundColor: action.color, + borderColor: action.color === 'red' ? 'purple' : null }; default: return state; } };
  • 51. 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> ) } }
  • 52. 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> ) } }
  • 53. 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; } };
  • 54. 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; } };
  • 55. 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; } };
  • 56. 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; } };
  • 57. 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; } };
  • 58. 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> ) } }
  • 59. 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> ) } }
  • 60. 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.
  • 61. Side-effects at one point in the update loop.
  • 62. Action Dispatcher Store View Action Async
  • 65. 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);
  • 66. 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);
  • 67. 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);
  • 68. 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);
  • 69. 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.
  • 70. 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.