SlideShare a Scribd company logo
1 of 31
Download to read offline
Let’s Redux
for people who use React but haven’t tried Redux
@josephj6802
React.js is Awesome
Building a complicate UI was never so easy
Plugins Dashboard
Widget Composer
ACL Term Languages
Building a complicate UI was never so easy
React.js is Awesome
• Easy to learn
• Manage State instead of DOM
• One-way Data Flow Model
• UI = fn(State)
Advantages
Absolutely a correct technical decision
PROBLEMS!!
React doesn’t We don’t have a
front-end application architecture.
“It worked well with simple
components, but as our interfaces
become more complicate we soon
found…”
Code Smells
• Delegation is difficult
• Top-down props
• Mixed concerns
• View logic
• Data fetching
• Data decoration
• Poor state management
• Component-specific
• Mutable
• Not maintainable
<WidgetsEdit/> Top-level Component
1469 lines in total!!
React.js = “Good” Parent
class WidgetsEdit extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
$.ajax(...).then((...) => {
// ... decorate data ...
this.setState(...)
});
}
render() {
let manyStates = that.state;
// ... view logic ...
return (
<ButtonNavList {...manyStates}>
<ButtonNavItem {...manyStates}/>
</ButtonNavList>
<StylePreview {...manyStates}/>
<CodeEditor {...manyStates}/>
)
}
}
who takes care of everything for childs
Preparing data, passing props, handling events for childs
22 Event Handlers
Child passes all events to its parent
because only the top-level
component should access state
Handling Children Events
Delegation or Not?
If your think NO, plz put inside…
• Pass all <ButtonNavItem/> required
props to <ButtonNavList/>
• Handle its events in <ButtonNavList/>
• Handle its events in <WidgetsEdit/>
If your think YES, plz keep there…
Handle child logic in top-level
component.
Both ways are not good…
Not	Convenient
Dirty!
Should <ButtonNavItem/>
appear in top-level as illustrated?
Fetching Data for Childs
No Separation of Concerns
Why Redux?
Not have children?
https://github.com/reactjs/redux/issues/151#issuecomment-173749456
Why Redux?
Solve all the mentioned issues
• Delegation is difficult easier
• Top-down props including events is not required
• Mixed Separation of concerns
• View logic
• Data fetching goes to ”Action”
• Data decoration goes to “Reducer”
• Poor Better state management
• Component App-specific
• Mutable Immutable
• Not Maintainable
Basic Concept
1. Action
2. Reducer
3. State
https://github.com/reactjs/redux/issues/151#issuecomment-134713785
1. Action
Pure Object
{
type: 'SORT_PLUGINS',
by: 'id',
direction: 'desc'
}
Minimum data which describes the change
Only the “type” property is required
1. Action
1-1. Action Creator
Pure function which creates an action
function sortPlugins(by, direction = 'desc') {
return {
type: 'SORT_PLUGINS',
by,
direction
};
}
Reusable, Portable, and Easy to Test
(Return promise for asynchronous action)
Make it easier to create an action
2. Reducer
Pure function which returns the next state
function reducer(state = {}, action) {
switch (action.type) {
case 'SORT_PLUGINS':
return {
...state,
plugins: {
orderBy: action.by,
orderByDirection: action.direction,
data: _.sortByOrder(state.data, action.by, 

action.direction)
}
};
default:
return state;
};
}
reducer(previousState, action) => state
Initial State
Always return current state
2. Reducer
reducer(prevState, action)
=> nextState
3. Store
A plain object which holds application state
{
plugins: {
data: [
{id: 1, name: 'AdRoll'},
{id: 2, name: 'Agile CRM'},
{id: 3, name: 'Brand Networks'}
],
orderBy: 'id',
orderByDirection: 'desc'
}
}
Dispatching actions is the only way to update store
Store is the only one state for the whole app
3. Store
3-1. Store Creation
with Reducer (the spec of your store)
store = createStore(reducer);
import {createStore} from 'redux';
let store = createStore(reducer);
The store provides several useful API methods
store.dispatch(sortPlugins('name', 'desc'));
3-2. Store APIs
store#dispatch
store#subscribe
let currentValue;
store.subscribe(() => {
let previousValue = currentValue;
currentValue = store.getState();
if (previousValue === currentValue) {
return;
}
// DO SOMETHING...
});
store#getState
Redux Data Flow
Reducer
Store
ActionActionAction
store = createStore(reducerFn);
store.subscribe(eventHandlerFn);
App
store.dispatch(actionCreatorFn);
reducerFn = (currentState, action) => nextState
Redux Data Flow
Reducer
Store
ActionActionAction
store = createStore(reducerFn);
store.subscribe(eventHandlerFn);
App
store.dispatch(actionCreatorFn);
reducerFn = (currentState, action) => nextState
That’s it!
• Super easy for both code and concept
• Pure functions & objects w/o side-effects
• Provides a better data flow for JS apps
• Not just for React.js apps
• jQuery or Node.js? No problem!
Redux and React?
First, let’s check the list again
• Delegation is easier
• Top-down props is not required
• Separation of concerns
• View logic
• Data fetching goes to ”Action”
• Data decoration goes to “Reducer”
• Better state management
• App-specific
• Immutable
• Maintainable
• Delegation is easier
• Top-down props is not required
React.js = “Good” Parent
class WidgetsEdit extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
$.ajax(...).then((...) => {
// ... decorate data ...
this.setState(...)
});
}
render() {
let manyStates = that.state;
// ... decorate state ...
return (
<ButtonNavList {...manyStates}>
<ButtonNavItem {...manyStates}/>
</ButtonNavList>
<StylePreview {...manyStates}/>
<CodeEditor {...manyStates}/>
)
}
}
who takes care of everything of its child components
Preparing data & handling events for child components
React + Redux = Bad Parent
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {fetchData} from ‘./actions';
class WidgetsEdit extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.props.dispatch(fetchData());
}
render() {
return (
<ButtonNavList>
<ButtonNavItem/>
<ButtonNavList>
<StylePreview/>
<CodeEditor/>
)
}
}
WidgetsEdit = connect(mapStateToProps)(WidgetsEdit);
who only cares about himself
Delegation = Preparing data and dispatching for itself
React.js w/ Redux
Child component connects to store by itself
import React from 'react';
import {connect} from 'react-redux';
import {modeSwitch} from './actions';
let StylePreview({url, dispatch} = props) => {
return (
<a onClick={() => dispatch(modeSwitch('mobile'))}>/>
Mobile View
</a>
<iframe src={url}/>
);
}
StylePreview = connect((state) => { // map state to props
return {
url: state.widget.url,
}
})(StylePreview);
… And dispatches actions by itself
Summary
• Good start to learn functional programming
• Add complexity but also add maintenance = worthy
• Single Store
• Time Travel (e.g. Undo) is possible
• No need to access React state API anymore
• Not only for React.js
Further Reading
https://egghead.io/series/getting-started-with-redux
egghead.io
Very good material for learning Redux!
Discussion - Store Structure
One Store - Could it possibly fit our application?
THANK YOU!
Let’s Redux!!

More Related Content

What's hot

What's hot (20)

Redux js
Redux jsRedux js
Redux js
 
React for Dummies
React for DummiesReact for Dummies
React for Dummies
 
Designing applications with Redux
Designing applications with ReduxDesigning applications with Redux
Designing applications with Redux
 
React & Redux
React & ReduxReact & Redux
React & Redux
 
React + Redux. Best practices
React + Redux.  Best practicesReact + Redux.  Best practices
React + Redux. Best practices
 
Getting started with Redux js
Getting started with Redux jsGetting started with Redux js
Getting started with Redux js
 
An Introduction to ReactJS
An Introduction to ReactJSAn Introduction to ReactJS
An Introduction to ReactJS
 
React state managmenet with Redux
React state managmenet with ReduxReact state managmenet with Redux
React state managmenet with Redux
 
React, Flux and a little bit of Redux
React, Flux and a little bit of ReduxReact, Flux and a little bit of Redux
React, Flux and a little bit of Redux
 
React + Redux + TypeScript === ♥
React + Redux + TypeScript === ♥React + Redux + TypeScript === ♥
React + Redux + TypeScript === ♥
 
The Road To Redux
The Road To ReduxThe Road To Redux
The Road To Redux
 
An introduction to React.js
An introduction to React.jsAn introduction to React.js
An introduction to React.js
 
Redux training
Redux trainingRedux training
Redux training
 
React.js and Redux overview
React.js and Redux overviewReact.js and Redux overview
React.js and Redux overview
 
React redux
React reduxReact redux
React redux
 
Academy PRO: React JS. Redux & Tooling
Academy PRO: React JS. Redux & ToolingAcademy PRO: React JS. Redux & Tooling
Academy PRO: React JS. Redux & Tooling
 
React JS and Redux
React JS and ReduxReact JS and Redux
React JS and Redux
 
React & redux
React & reduxReact & redux
React & redux
 
React, Redux, ES2015 by Max Petruck
React, Redux, ES2015   by Max PetruckReact, Redux, ES2015   by Max Petruck
React, Redux, ES2015 by Max Petruck
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux Introduction
 

Similar to Let's Redux!

[Final] ReactJS presentation
[Final] ReactJS presentation[Final] ReactJS presentation
[Final] ReactJS presentation
洪 鹏发
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
Evan Schultz
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
Andy Peterson
 

Similar to Let's Redux! (20)

[Final] ReactJS presentation
[Final] ReactJS presentation[Final] ReactJS presentation
[Final] ReactJS presentation
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
 
Up and Running with ReactJS
Up and Running with ReactJSUp and Running with ReactJS
Up and Running with ReactJS
 
Using React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsUsing React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIs
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
 
React js
React jsReact js
React js
 
ReactJS presentation.pptx
ReactJS presentation.pptxReactJS presentation.pptx
ReactJS presentation.pptx
 
Workshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux AdvancedWorkshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux Advanced
 
Workshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareWorkshop 22: React-Redux Middleware
Workshop 22: React-Redux Middleware
 
2018 02-22 React, Redux & Building Applications that Scale | React
2018 02-22 React, Redux & Building Applications that Scale | React2018 02-22 React, Redux & Building Applications that Scale | React
2018 02-22 React, Redux & Building Applications that Scale | React
 
React on Rails - RailsConf 2017 (Phoenix)
 React on Rails - RailsConf 2017 (Phoenix) React on Rails - RailsConf 2017 (Phoenix)
React on Rails - RailsConf 2017 (Phoenix)
 
Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]
 
Workshop 19: ReactJS Introduction
Workshop 19: ReactJS IntroductionWorkshop 19: ReactJS Introduction
Workshop 19: ReactJS Introduction
 
React lecture
React lectureReact lecture
React lecture
 
Intro react js
Intro react jsIntro react js
Intro react js
 
Enhance react app with patterns - part 1: higher order component
Enhance react app with patterns - part 1: higher order componentEnhance react app with patterns - part 1: higher order component
Enhance react app with patterns - part 1: higher order component
 
react redux.pdf
react redux.pdfreact redux.pdf
react redux.pdf
 
React.js+Redux Workshops
React.js+Redux WorkshopsReact.js+Redux Workshops
React.js+Redux Workshops
 
ReactJS - A quick introduction to Awesomeness
ReactJS - A quick introduction to AwesomenessReactJS - A quick introduction to Awesomeness
ReactJS - A quick introduction to Awesomeness
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
 

More from Joseph Chiang

前端的未來 - 前端工程實務訓練
前端的未來 - 前端工程實務訓練前端的未來 - 前端工程實務訓練
前端的未來 - 前端工程實務訓練
Joseph Chiang
 
Performance 入門 - 前端工程開發實務訓練
Performance 入門 - 前端工程開發實務訓練Performance 入門 - 前端工程開發實務訓練
Performance 入門 - 前端工程開發實務訓練
Joseph Chiang
 
Debugging - 前端工程開發實務訓練
 Debugging - 前端工程開發實務訓練 Debugging - 前端工程開發實務訓練
Debugging - 前端工程開發實務訓練
Joseph Chiang
 
Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練
Joseph Chiang
 
Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練
Joseph Chiang
 
前端工程開發實務訓練
前端工程開發實務訓練前端工程開發實務訓練
前端工程開發實務訓練
Joseph Chiang
 
YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練
Joseph Chiang
 
CSS 入門 - 前端工程開發實務訓練
CSS 入門 - 前端工程開發實務訓練CSS 入門 - 前端工程開發實務訓練
CSS 入門 - 前端工程開發實務訓練
Joseph Chiang
 
HTML 入門 - 前端工程開發實務訓練
HTML 入門 - 前端工程開發實務訓練HTML 入門 - 前端工程開發實務訓練
HTML 入門 - 前端工程開發實務訓練
Joseph Chiang
 

More from Joseph Chiang (20)

不断归零的前端人生 - 2016 中国软件开发者大会
不断归零的前端人生 - 2016 中国软件开发者大会不断归零的前端人生 - 2016 中国软件开发者大会
不断归零的前端人生 - 2016 中国软件开发者大会
 
Automatic Functional Testing with Selenium and SauceLabs
Automatic Functional Testing with Selenium and SauceLabsAutomatic Functional Testing with Selenium and SauceLabs
Automatic Functional Testing with Selenium and SauceLabs
 
From Hacker to Programmer (w/ Webpack, Babel and React)
From Hacker to Programmer (w/ Webpack, Babel and React)From Hacker to Programmer (w/ Webpack, Babel and React)
From Hacker to Programmer (w/ Webpack, Babel and React)
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
 
F2E for Enterprise
F2E for EnterpriseF2E for Enterprise
F2E for Enterprise
 
JavaScript Code Quality
JavaScript Code QualityJavaScript Code Quality
JavaScript Code Quality
 
F2E, the Keystone
F2E, the KeystoneF2E, the Keystone
F2E, the Keystone
 
前端的未來 - 前端工程實務訓練
前端的未來 - 前端工程實務訓練前端的未來 - 前端工程實務訓練
前端的未來 - 前端工程實務訓練
 
Performance 入門 - 前端工程開發實務訓練
Performance 入門 - 前端工程開發實務訓練Performance 入門 - 前端工程開發實務訓練
Performance 入門 - 前端工程開發實務訓練
 
Debugging - 前端工程開發實務訓練
 Debugging - 前端工程開發實務訓練 Debugging - 前端工程開發實務訓練
Debugging - 前端工程開發實務訓練
 
Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練
 
Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練
 
前端工程開發實務訓練
前端工程開發實務訓練前端工程開發實務訓練
前端工程開發實務訓練
 
YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練
 
CSS 入門 - 前端工程開發實務訓練
CSS 入門 - 前端工程開發實務訓練CSS 入門 - 前端工程開發實務訓練
CSS 入門 - 前端工程開發實務訓練
 
HTML 入門 - 前端工程開發實務訓練
HTML 入門 - 前端工程開發實務訓練HTML 入門 - 前端工程開發實務訓練
HTML 入門 - 前端工程開發實務訓練
 
模块加载策略 - 2012 SDCC, 北京
模块加载策略 - 2012 SDCC, 北京模块加载策略 - 2012 SDCC, 北京
模块加载策略 - 2012 SDCC, 北京
 
YUI is Sexy (for JSDC.tw)
YUI is Sexy (for JSDC.tw)YUI is Sexy (for JSDC.tw)
YUI is Sexy (for JSDC.tw)
 
YUI is Sexy - 使用 YUI 作為開發基礎
YUI is Sexy - 使用 YUI 作為開發基礎YUI is Sexy - 使用 YUI 作為開發基礎
YUI is Sexy - 使用 YUI 作為開發基礎
 
Git - The Social Coding System
Git - The Social Coding SystemGit - The Social Coding System
Git - The Social Coding System
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 

Let's Redux!

  • 1. Let’s Redux for people who use React but haven’t tried Redux @josephj6802
  • 2. React.js is Awesome Building a complicate UI was never so easy Plugins Dashboard Widget Composer ACL Term Languages
  • 3. Building a complicate UI was never so easy React.js is Awesome • Easy to learn • Manage State instead of DOM • One-way Data Flow Model • UI = fn(State) Advantages Absolutely a correct technical decision
  • 4. PROBLEMS!! React doesn’t We don’t have a front-end application architecture. “It worked well with simple components, but as our interfaces become more complicate we soon found…”
  • 5. Code Smells • Delegation is difficult • Top-down props • Mixed concerns • View logic • Data fetching • Data decoration • Poor state management • Component-specific • Mutable • Not maintainable <WidgetsEdit/> Top-level Component 1469 lines in total!!
  • 6. React.js = “Good” Parent class WidgetsEdit extends Component { constructor(props) { super(props); } componentWillMount() { $.ajax(...).then((...) => { // ... decorate data ... this.setState(...) }); } render() { let manyStates = that.state; // ... view logic ... return ( <ButtonNavList {...manyStates}> <ButtonNavItem {...manyStates}/> </ButtonNavList> <StylePreview {...manyStates}/> <CodeEditor {...manyStates}/> ) } } who takes care of everything for childs Preparing data, passing props, handling events for childs
  • 7. 22 Event Handlers Child passes all events to its parent because only the top-level component should access state Handling Children Events
  • 8. Delegation or Not? If your think NO, plz put inside… • Pass all <ButtonNavItem/> required props to <ButtonNavList/> • Handle its events in <ButtonNavList/> • Handle its events in <WidgetsEdit/> If your think YES, plz keep there… Handle child logic in top-level component. Both ways are not good… Not Convenient Dirty! Should <ButtonNavItem/> appear in top-level as illustrated?
  • 9. Fetching Data for Childs No Separation of Concerns
  • 10. Why Redux? Not have children? https://github.com/reactjs/redux/issues/151#issuecomment-173749456
  • 11. Why Redux? Solve all the mentioned issues • Delegation is difficult easier • Top-down props including events is not required • Mixed Separation of concerns • View logic • Data fetching goes to ”Action” • Data decoration goes to “Reducer” • Poor Better state management • Component App-specific • Mutable Immutable • Not Maintainable
  • 12. Basic Concept 1. Action 2. Reducer 3. State https://github.com/reactjs/redux/issues/151#issuecomment-134713785
  • 13. 1. Action Pure Object { type: 'SORT_PLUGINS', by: 'id', direction: 'desc' } Minimum data which describes the change Only the “type” property is required
  • 15. 1-1. Action Creator Pure function which creates an action function sortPlugins(by, direction = 'desc') { return { type: 'SORT_PLUGINS', by, direction }; } Reusable, Portable, and Easy to Test (Return promise for asynchronous action) Make it easier to create an action
  • 16. 2. Reducer Pure function which returns the next state function reducer(state = {}, action) { switch (action.type) { case 'SORT_PLUGINS': return { ...state, plugins: { orderBy: action.by, orderByDirection: action.direction, data: _.sortByOrder(state.data, action.by, 
 action.direction) } }; default: return state; }; } reducer(previousState, action) => state Initial State Always return current state
  • 18. 3. Store A plain object which holds application state { plugins: { data: [ {id: 1, name: 'AdRoll'}, {id: 2, name: 'Agile CRM'}, {id: 3, name: 'Brand Networks'} ], orderBy: 'id', orderByDirection: 'desc' } } Dispatching actions is the only way to update store Store is the only one state for the whole app
  • 20. 3-1. Store Creation with Reducer (the spec of your store) store = createStore(reducer); import {createStore} from 'redux'; let store = createStore(reducer); The store provides several useful API methods
  • 21. store.dispatch(sortPlugins('name', 'desc')); 3-2. Store APIs store#dispatch store#subscribe let currentValue; store.subscribe(() => { let previousValue = currentValue; currentValue = store.getState(); if (previousValue === currentValue) { return; } // DO SOMETHING... }); store#getState
  • 22. Redux Data Flow Reducer Store ActionActionAction store = createStore(reducerFn); store.subscribe(eventHandlerFn); App store.dispatch(actionCreatorFn); reducerFn = (currentState, action) => nextState
  • 23. Redux Data Flow Reducer Store ActionActionAction store = createStore(reducerFn); store.subscribe(eventHandlerFn); App store.dispatch(actionCreatorFn); reducerFn = (currentState, action) => nextState That’s it! • Super easy for both code and concept • Pure functions & objects w/o side-effects • Provides a better data flow for JS apps • Not just for React.js apps • jQuery or Node.js? No problem!
  • 24. Redux and React? First, let’s check the list again • Delegation is easier • Top-down props is not required • Separation of concerns • View logic • Data fetching goes to ”Action” • Data decoration goes to “Reducer” • Better state management • App-specific • Immutable • Maintainable • Delegation is easier • Top-down props is not required
  • 25. React.js = “Good” Parent class WidgetsEdit extends Component { constructor(props) { super(props); } componentWillMount() { $.ajax(...).then((...) => { // ... decorate data ... this.setState(...) }); } render() { let manyStates = that.state; // ... decorate state ... return ( <ButtonNavList {...manyStates}> <ButtonNavItem {...manyStates}/> </ButtonNavList> <StylePreview {...manyStates}/> <CodeEditor {...manyStates}/> ) } } who takes care of everything of its child components Preparing data & handling events for child components
  • 26. React + Redux = Bad Parent import React, {Component} from 'react'; import {connect} from 'react-redux'; import {fetchData} from ‘./actions'; class WidgetsEdit extends Component { constructor(props) { super(props); } componentWillMount() { this.props.dispatch(fetchData()); } render() { return ( <ButtonNavList> <ButtonNavItem/> <ButtonNavList> <StylePreview/> <CodeEditor/> ) } } WidgetsEdit = connect(mapStateToProps)(WidgetsEdit); who only cares about himself Delegation = Preparing data and dispatching for itself
  • 27. React.js w/ Redux Child component connects to store by itself import React from 'react'; import {connect} from 'react-redux'; import {modeSwitch} from './actions'; let StylePreview({url, dispatch} = props) => { return ( <a onClick={() => dispatch(modeSwitch('mobile'))}>/> Mobile View </a> <iframe src={url}/> ); } StylePreview = connect((state) => { // map state to props return { url: state.widget.url, } })(StylePreview); … And dispatches actions by itself
  • 28. Summary • Good start to learn functional programming • Add complexity but also add maintenance = worthy • Single Store • Time Travel (e.g. Undo) is possible • No need to access React state API anymore • Not only for React.js
  • 30. Discussion - Store Structure One Store - Could it possibly fit our application?