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

PDF
Stay with React.js in 2020
TXT
Data20161007
PDF
React.js workshop by tech47.in
PDF
안드로이드 세미나 2
KEY
안드로이드 세미나 2
PDF
React.js: Beyond the Browser
PDF
Road to react hooks
PDF
Improving android experience for both users and developers
Stay with React.js in 2020
Data20161007
React.js workshop by tech47.in
안드로이드 세미나 2
안드로이드 세미나 2
React.js: Beyond the Browser
Road to react hooks
Improving android experience for both users and developers

What's hot (20)

PDF
Droidcon2013 android experience lahoda
PPTX
Magento Dependency Injection
PDF
Egghead redux-cheat-sheet-3-2-1
PPTX
Android 3
PPTX
Handling action bar in Android
PDF
Quick Intro to Android Development
PDF
Deep Dive into React Hooks
DOCX
culadora cientifica en java
DOCX
Ip project
PDF
State of the state
PDF
MVI - Managing State The Kotlin Way
PDF
Delivering a Responsive UI
PDF
Android Testing
PDF
A comprehensive guide on developing responsive and common react filter component
KEY
jrubykaigi2010-lt-rubeus
PPTX
PDF
Effective Android Data Binding
PDF
Windows 8 Training Fundamental - 1
PPT
jQuery 1.7 Events
Droidcon2013 android experience lahoda
Magento Dependency Injection
Egghead redux-cheat-sheet-3-2-1
Android 3
Handling action bar in Android
Quick Intro to Android Development
Deep Dive into React Hooks
culadora cientifica en java
Ip project
State of the state
MVI - Managing State The Kotlin Way
Delivering a Responsive UI
Android Testing
A comprehensive guide on developing responsive and common react filter component
jrubykaigi2010-lt-rubeus
Effective Android Data Binding
Windows 8 Training Fundamental - 1
jQuery 1.7 Events
Ad

Viewers also liked (17)

PPTX
Students co creating course content and evaluating their own learning
PDF
The Fourth Screen v4.2
PDF
Esos Raros Lenguajes Nuevos
PDF
Making Student Thinking Visible v4
PDF
Tales of Learning and the Gifts of Footprints v4.2
PDF
Lemoine brandon ppp
PPTX
Distribucion normal, binomial y poisson
DOCX
Taller 1. conflicto armado chcv (3)
PDF
III ciclo unidad_de_estadistica
PDF
III ciclo unidad_de_probabilidad
PPTX
KBM_WomenInBusinessAwards
PPTX
Voz pasiva y voz activa
PDF
LEG.2016.Wins
ODS
Actividad2 m1 calc_bas (3)
PDF
Manual de Gerador de Calor para Sauna Seca Sodramar
PDF
Gdz ros mova_rydyakov_2014
PPTX
The Spine and Its Vulnerability to Disc Rupture and Herniation
Students co creating course content and evaluating their own learning
The Fourth Screen v4.2
Esos Raros Lenguajes Nuevos
Making Student Thinking Visible v4
Tales of Learning and the Gifts of Footprints v4.2
Lemoine brandon ppp
Distribucion normal, binomial y poisson
Taller 1. conflicto armado chcv (3)
III ciclo unidad_de_estadistica
III ciclo unidad_de_probabilidad
KBM_WomenInBusinessAwards
Voz pasiva y voz activa
LEG.2016.Wins
Actividad2 m1 calc_bas (3)
Manual de Gerador de Calor para Sauna Seca Sodramar
Gdz ros mova_rydyakov_2014
The Spine and Its Vulnerability to Disc Rupture and Herniation
Ad

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

PDF
Higher-Order Components — Ilya Gelman
PDF
Why react matters
PDF
React lecture
PDF
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
PDF
Introduction to React & Redux
PDF
Introduction to ReactJS and Redux
PDF
Advanced React Component Patterns - ReactNext 2018
PPTX
The productive developer guide to React
PDF
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
PDF
Recompacting your react application
PDF
Advanced redux
PDF
React JS Hooks Sheet .pdf
PPTX
React 16: new features and beyond
PDF
Structuring React.js Components
PDF
4Developers 2018: Structuring React components (Bartłomiej Witczak)
PDF
Redux Deep Dive - ReactFoo Pune 2018
PDF
Let's discover React and Redux with TypeScript
PPTX
Maintaining sanity in a large redux app
PDF
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
PDF
React & Redux
Higher-Order Components — Ilya Gelman
Why react matters
React lecture
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
Introduction to React & Redux
Introduction to ReactJS and Redux
Advanced React Component Patterns - ReactNext 2018
The productive developer guide to React
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
Recompacting your react application
Advanced redux
React JS Hooks Sheet .pdf
React 16: new features and beyond
Structuring React.js Components
4Developers 2018: Structuring React components (Bartłomiej Witczak)
Redux Deep Dive - ReactFoo Pune 2018
Let's discover React and Redux with TypeScript
Maintaining sanity in a large redux app
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
React & Redux

Recently uploaded (20)

PDF
Automation-in-Manufacturing-Chapter-Introduction.pdf
PPTX
Lecture Notes Electrical Wiring System Components
PDF
Unit I ESSENTIAL OF DIGITAL MARKETING.pdf
PDF
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
PDF
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
PDF
Digital Logic Computer Design lecture notes
PDF
Embodied AI: Ushering in the Next Era of Intelligent Systems
PPTX
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
PDF
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
PPTX
OOP with Java - Java Introduction (Basics)
PDF
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
PDF
Operating System & Kernel Study Guide-1 - converted.pdf
PPTX
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
PPTX
Internet of Things (IOT) - A guide to understanding
PPT
Project quality management in manufacturing
PPTX
Current and future trends in Computer Vision.pptx
PDF
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
PPTX
UNIT 4 Total Quality Management .pptx
PPTX
UNIT-1 - COAL BASED THERMAL POWER PLANTS
PPTX
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
Automation-in-Manufacturing-Chapter-Introduction.pdf
Lecture Notes Electrical Wiring System Components
Unit I ESSENTIAL OF DIGITAL MARKETING.pdf
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
Digital Logic Computer Design lecture notes
Embodied AI: Ushering in the Next Era of Intelligent Systems
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
OOP with Java - Java Introduction (Basics)
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
Operating System & Kernel Study Guide-1 - converted.pdf
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
Internet of Things (IOT) - A guide to understanding
Project quality management in manufacturing
Current and future trends in Computer Vision.pptx
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
UNIT 4 Total Quality Management .pptx
UNIT-1 - COAL BASED THERMAL POWER PLANTS
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx

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.