SlideShare uma empresa Scribd logo
1 de 42
Baixar para ler offline
Image by mulad
Many people choose to
think of React as the V in
MVC.
– “Why React?” in React documentation
“
MVC in Theory
Image by mulad
Model( ͡° ͜ʖ ͡°)
View
Controller
MVC in Practice
Image by mulad
View Model Model
Model
Model
Model
View Model
View Model
View Model ಠ_ಠ
Isolated (“Dumb”) Components
Parent
Child
Props Callbacks
Maximize your use of “dumb” components.
Advantages of Isolated Components
• Helps with code reuse.
• Helps with testing.
• Makes it easy to reason about your code.
Image by mulad
Sources of Those Benefits
• Dumb components are isolation from the rest of the
application.
• Dumb components are mostly stateless.
Image by mulad
Trouble with State
• A lot of us were raised on OOP. Objects are stateful.
• The effect of calling a method depends on the arguments and
the object’s state.
• Very painful to test.
• Very hard to understand.
• Aims to mimic the real world.
• But why replicate the unnecessary complexity?
Image by mulad
Alternative: Pure Functions
• The output of a pure function depends only on inputs.
• Pure function has no side-effects.
• Much easier to understand.
• Much easier to test.
• Very easy to build through composition.
Image by mulad
Truly Stateless Components
Image by mulad
function HelloMessage(props) {
return <div>Hello {props.name}</div>;
}
Even Better
Image by mulad
const HelloMessage = (props) => <div>Hello {props.name}</div>;
Use stateless components whenever you can.
Where Does Business Logic Go?
• Each component gets props from its parent.
• Each component transmits actions to the parent.
• Turtles all the way down up?
• Top-level components need to be a bit smarter!
• We’ll call them “container components”.
Image by mulad
Linking Containers with Models
Image by mulad
Container Model
ModelContainer
Nevermind…
Should We Use the Container’s State?
• We could, but so much for separation of concerns…
Image by mulad
What If We Did It the React Way?
???
Container Component
Props Callbacks
What If We Did It the React Way?
State Container
Container Component
Props Callbacks
Flux Architecture
State Container
Container Component
Change events Actions
Handling Data in the State Container
Component
StoreComponent
Dispatcher
Action
Handling Data in the State Container
Component
Store
API, etc.
Component
Dispatcher
Action(s)Action

Creator
We’ll see another

way of doing this.
Redux
A Better State Container
• https://github.com/rackt/redux
• Pretty much the dominant way of doing Flux with React
today.
• Key concepts: a single store + state “reducers”.
• Can a single store be a good idea?
• What the heck is a “reducer”?
Reducer Functions
• Basic reduce():
function addOneValue (value, state) {
return state + value;
}
[1,2,3,4,5].reduce(addOneValue, 0);
• Running through the items:
1: 0 => 1
2: 1 => 3
3: 3 => 6
4: 6 => 10
5: 10 => 15
Action Reducers in Redux
• Take an action and a state, return a new state.
• Your app’s state is a reduction over the actions.
• Each reducer operates on a subset of the global state.
• Simple reducers are combined into complex ones.
Creating an Action
const UPDATE_NOTE_CONTENT = 'App/UPDATE_NOTE_CONTENT';
function updateNoteContent(noteId, newContent) {
return {
type: UPDATE_NOTE_CONTENT,
payload: {
noteId: noteId,
newContent: newContent
}
}
}
Creating an Action, more ES6
const UPDATE_NOTE_CONTENT = 'App/UPDATE_NOTE_CONTENT';
const updateNoteContent = (noteId, newContent) => ({
type: UPDATE_NOTE_CONTENT,
payload: {noteId, newContent}
});
A Reducer
export const notes = createReducer({
[UPDATE_NOTE_CONTENT]: (state, action) => state.setIn(
['byId', action.payload.noteId, 'html'],
action.payload.newContent
),
[SOME_OTHER_ACTION]: (state, action) => {
// do something else or just
return state;
}),
});
A Reducer, more ES5ish
export const notes = createReducer({
[UPDATE_NOTE_CONTENT]: function (state, action) {
return state.setIn(
['byId', action.payload.noteId, 'html'],
action.payload.newContent
);
},
[SOME_OTHER_ACTION]: function (state, action) {
// do something else or just
return state;
},
});
Why Is This a Good Idea?
• Reducers are pure functions – easy to understand, easy to
test.
• Reducers are synchronous.
• Data logic is 100% separated from view logic.
• You can still have modularity by combining reducers.
• New opportunities for tools.
How Do We Avoid Mutating State?
• Reducers are supposed to not change the old state. But how
do we keep them honest?
• One option is to clone the object every time.
• “Immutable.JS” is the library to use.
var newData = data.setIn(
['foo', 'bar', 'baz'],
42
);
• This is a key building block for stateless architecture.
The Reducer Example Again
export const notes = createReducer({
[UPDATE_NOTE_CONTENT]: (state, action) => state.setIn(
['byId', action.payload.noteId, 'html'],
action.payload.newContent
),
[SOME_OTHER_ACTION]: (state, action) => {
// do something else or just
return state;
}),
});
Connecting Container Components
import { connect } from 'react-redux';
export default connect(
mapStateToProps,
mapDispatchToProps,
)(MainPage);
React-Redux Mapping Functions
function mapStateToProps(state) {
const notesAsJS = state.notes.toJS();
return {
notes: notesAsJS.ordered.map((id) => notesAsJS.byId[id])
};
}
function mapDispatchToProps(dispatch) {
return {
onContentChange: (noteId, newContent) =>
dispatch(noteActions.updateNoteContent(
noteId, newContent)),
};
}
Handling Asyncronous Actions
• Option 1: “Smart” actions creators.
• Option 2: Middleware.
• Option 2′: React Sagas.
Smart Action Creators
• Call an action creator to initiate a request.
• The action creator emits an action to inform everyone that a
request was made.
• The action creator makes a request.
• If the request succeeds, the action creator emits an action to
inform everyone that a request was completed. (Same for
failure and timeout.)
• The details of interacting with the server should be pushed
into a module.
An Example, Part 1
function makeFetchNotesAction(status, data) {
return {
type: FETCH_NOTES,
payload: {
status: status,
data: data
}
};
}
An Example, Part 1
export function fetchNotes() {
return dispatch => {
dispatch(makeFetchNotesAction('request'));
return fetchData()
.then(json => dispatch(makeFetchNotesAction('success', json)))
.catch(error => dispatch(makeFetchNotesAction('error', error)));
};
}
Alternatively: Redux Middleware
• A middleware is a function that allows you to capture actions
and do something before they get to the reducers.
• This can include things like API calls.
• More generally, the sky is the limit.
• Perhaps a little too generic for many cases.
Alternative: Redux Sagas
• A middleware that works with generators.
• Awesome, if you understand generators.
• Can simplify complex workflows.
• Very new.
Redux Sagas Example
function* fetchNotesForStack(action) {
const stackId = action.payload.stackId;
yield put(getNotes.request());
const {data, error} = yield dataApi.getNotesForStack(stackId);
if (!error) {
yield put(getNotes.success(organizeNotes(data.notes)));
} else {
yield put(getNotes.failure(error));
}
}
function* watchFetchNotesForStack() {
yield* takeEvery(SELECT_STACK, fetchNotesForStack);
}
Testing Is Easy
describe('on ADD_NOTE', () => {
it('should create a new note', () => {
const getNoteCount = () => initialState.toJS().ordered.length;
const previousCount = getNoteCount();
const newState = notesReducer(initialState, {type: ADD_NOTE});
assert.strictEqual(previousCount + 1, getNoteCount());
const newNoteId = newState.toJS().ordered[0];
const newNoteHtml = newState.getIn(['byId', newNoteId, 'html']);
assert.strictEqual(newNoteHtml, 'No content');
});
});
Caveats
• Its addictive.
• You won’t be happy using anything else.
• Your friends might not understand your obsession.
THANK YOU!
Yuri Takhteyev
@qaramazov
rangle
CTO, Rangle.io
Some rights reserved - Creative Commons 2.0 by-sa

Mais conteúdo relacionado

Mais procurados

Designing applications with Redux
Designing applications with ReduxDesigning applications with Redux
Designing applications with ReduxFernando Daciuk
 
React + Redux + TypeScript === ♥
React + Redux + TypeScript === ♥React + Redux + TypeScript === ♥
React + Redux + TypeScript === ♥Remo Jansen
 
React for Dummies
React for DummiesReact for Dummies
React for DummiesMitch Chen
 
An Introduction to ReactJS
An Introduction to ReactJSAn Introduction to ReactJS
An Introduction to ReactJSAll Things Open
 
Getting started with Redux js
Getting started with Redux jsGetting started with Redux js
Getting started with Redux jsCitrix
 
React.js and Redux overview
React.js and Redux overviewReact.js and Redux overview
React.js and Redux overviewAlex Bachuk
 
React state managmenet with Redux
React state managmenet with ReduxReact state managmenet with Redux
React state managmenet with ReduxVedran Blaženka
 
React + Redux. Best practices
React + Redux.  Best practicesReact + Redux.  Best practices
React + Redux. Best practicesClickky
 
Academy PRO: React JS. Redux & Tooling
Academy PRO: React JS. Redux & ToolingAcademy PRO: React JS. Redux & Tooling
Academy PRO: React JS. Redux & ToolingBinary Studio
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux IntroductionNikolaus Graf
 
Redux training
Redux trainingRedux training
Redux trainingdasersoft
 
Introduction to React & Redux
Introduction to React & ReduxIntroduction to React & Redux
Introduction to React & ReduxBoris Dinkevich
 
Introduction to react and redux
Introduction to react and reduxIntroduction to react and redux
Introduction to react and reduxCuong Ho
 

Mais procurados (20)

Designing applications with Redux
Designing applications with ReduxDesigning applications with Redux
Designing applications with Redux
 
React + Redux + TypeScript === ♥
React + Redux + TypeScript === ♥React + Redux + TypeScript === ♥
React + Redux + TypeScript === ♥
 
React for Dummies
React for DummiesReact for Dummies
React for Dummies
 
An Introduction to ReactJS
An Introduction to ReactJSAn Introduction to ReactJS
An Introduction to ReactJS
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
 
Getting started with Redux js
Getting started with Redux jsGetting started with Redux js
Getting started with Redux js
 
React.js and Redux overview
React.js and Redux overviewReact.js and Redux overview
React.js and Redux overview
 
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
 
Angular redux
Angular reduxAngular redux
Angular redux
 
React js
React jsReact js
React js
 
React redux
React reduxReact redux
React redux
 
React state managmenet with Redux
React state managmenet with ReduxReact state managmenet with Redux
React state managmenet with Redux
 
React + Redux. Best practices
React + Redux.  Best practicesReact + Redux.  Best practices
React + Redux. Best practices
 
Academy PRO: React JS. Redux & Tooling
Academy PRO: React JS. Redux & ToolingAcademy PRO: React JS. Redux & Tooling
Academy PRO: React JS. Redux & Tooling
 
React / Redux Architectures
React / Redux ArchitecturesReact / Redux Architectures
React / Redux Architectures
 
Using redux
Using reduxUsing redux
Using redux
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux Introduction
 
Redux training
Redux trainingRedux training
Redux training
 
Introduction to React & Redux
Introduction to React & ReduxIntroduction to React & Redux
Introduction to React & Redux
 
Introduction to react and redux
Introduction to react and reduxIntroduction to react and redux
Introduction to react and redux
 

Destaque

React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesomeAndrew Hull
 
React.js in real world apps.
React.js in real world apps. React.js in real world apps.
React.js in real world apps. Emanuele DelBono
 
Robust web apps with React.js
Robust web apps with React.jsRobust web apps with React.js
Robust web apps with React.jsMax Klymyshyn
 
Angular js com diretivas
Angular js com diretivasAngular js com diretivas
Angular js com diretivasMatheus Lima
 
Apresentação AngularJS - Angular UI
Apresentação AngularJS - Angular UIApresentação AngularJS - Angular UI
Apresentação AngularJS - Angular UICecília Rosa
 
An Intense Overview of the React Ecosystem
An Intense Overview of the React EcosystemAn Intense Overview of the React Ecosystem
An Intense Overview of the React EcosystemRami Sayar
 
React, Flux y React native
React, Flux y React nativeReact, Flux y React native
React, Flux y React nativeEduard Tomàs
 
React – ¿Qué es React.js?
React – ¿Qué es React.js?React – ¿Qué es React.js?
React – ¿Qué es React.js?Gorka Magaña
 
JSConf US 2014: Building Isomorphic Apps
JSConf US 2014: Building Isomorphic AppsJSConf US 2014: Building Isomorphic Apps
JSConf US 2014: Building Isomorphic AppsSpike Brehm
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Astrails
 
Arquitetura Orientada a Servicos (SOA)
Arquitetura Orientada a Servicos (SOA)Arquitetura Orientada a Servicos (SOA)
Arquitetura Orientada a Servicos (SOA)Marcelo Sávio
 
Criando serviços com AngularJS
Criando serviços com AngularJSCriando serviços com AngularJS
Criando serviços com AngularJSRodrigo Branas
 

Destaque (20)

React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesome
 
React.js in real world apps.
React.js in real world apps. React.js in real world apps.
React.js in real world apps.
 
How to Redux
How to ReduxHow to Redux
How to Redux
 
Robust web apps with React.js
Robust web apps with React.jsRobust web apps with React.js
Robust web apps with React.js
 
Flux and redux
Flux and reduxFlux and redux
Flux and redux
 
Reducers+flux=redux
Reducers+flux=reduxReducers+flux=redux
Reducers+flux=redux
 
React&redux
React&reduxReact&redux
React&redux
 
Redux vs Alt
Redux vs AltRedux vs Alt
Redux vs Alt
 
Angular js com diretivas
Angular js com diretivasAngular js com diretivas
Angular js com diretivas
 
Apresentação AngularJS - Angular UI
Apresentação AngularJS - Angular UIApresentação AngularJS - Angular UI
Apresentação AngularJS - Angular UI
 
An Intense Overview of the React Ecosystem
An Intense Overview of the React EcosystemAn Intense Overview of the React Ecosystem
An Intense Overview of the React Ecosystem
 
React, Flux y React native
React, Flux y React nativeReact, Flux y React native
React, Flux y React native
 
React – ¿Qué es React.js?
React – ¿Qué es React.js?React – ¿Qué es React.js?
React – ¿Qué es React.js?
 
JSConf US 2014: Building Isomorphic Apps
JSConf US 2014: Building Isomorphic AppsJSConf US 2014: Building Isomorphic Apps
JSConf US 2014: Building Isomorphic Apps
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.
 
React. Flux. Redux
React. Flux. ReduxReact. Flux. Redux
React. Flux. Redux
 
Soa Fundamentos
Soa FundamentosSoa Fundamentos
Soa Fundamentos
 
Arquitetura Orientada a Servicos (SOA)
Arquitetura Orientada a Servicos (SOA)Arquitetura Orientada a Servicos (SOA)
Arquitetura Orientada a Servicos (SOA)
 
Angular js
Angular jsAngular js
Angular js
 
Criando serviços com AngularJS
Criando serviços com AngularJSCriando serviços com AngularJS
Criando serviços com AngularJS
 

Semelhante a Building React Applications with Redux

Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsJeff Durta
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz
 
Gitter marionette deck
Gitter marionette deckGitter marionette deck
Gitter marionette deckMike Bartlett
 
React gsg presentation with ryan jung &amp; elias malik
React   gsg presentation with ryan jung &amp; elias malikReact   gsg presentation with ryan jung &amp; elias malik
React gsg presentation with ryan jung &amp; elias malikLama K Banna
 
React state management with Redux and MobX
React state management with Redux and MobXReact state management with Redux and MobX
React state management with Redux and MobXDarko Kukovec
 
React && React Native workshop
React && React Native workshopReact && React Native workshop
React && React Native workshopStacy Goh
 
an Introduction to Redux
an Introduction to Reduxan Introduction to Redux
an Introduction to ReduxAmin Ashtiani
 
Intro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScriptIntro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScriptjasonsich
 
Web technologies-course 12.pptx
Web technologies-course 12.pptxWeb technologies-course 12.pptx
Web technologies-course 12.pptxStefan Oprea
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsJeff Durta
 
React.js - The Dawn of Virtual DOM
React.js - The Dawn of Virtual DOMReact.js - The Dawn of Virtual DOM
React.js - The Dawn of Virtual DOMJimit Shah
 
React.js - and how it changed our thinking about UI
React.js - and how it changed our thinking about UIReact.js - and how it changed our thinking about UI
React.js - and how it changed our thinking about UIMarcin Grzywaczewski
 
O365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - MaterialO365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - MaterialThomas Daly
 
[Final] ReactJS presentation
[Final] ReactJS presentation[Final] ReactJS presentation
[Final] ReactJS presentation洪 鹏发
 
Workshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareWorkshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareVisual Engineering
 
Workshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux AdvancedWorkshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux AdvancedVisual Engineering
 

Semelhante a Building React Applications with Redux (20)

Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
 
Gitter marionette deck
Gitter marionette deckGitter marionette deck
Gitter marionette deck
 
React gsg presentation with ryan jung &amp; elias malik
React   gsg presentation with ryan jung &amp; elias malikReact   gsg presentation with ryan jung &amp; elias malik
React gsg presentation with ryan jung &amp; elias malik
 
React state management with Redux and MobX
React state management with Redux and MobXReact state management with Redux and MobX
React state management with Redux and MobX
 
React.js+Redux Workshops
React.js+Redux WorkshopsReact.js+Redux Workshops
React.js+Redux Workshops
 
React && React Native workshop
React && React Native workshopReact && React Native workshop
React && React Native workshop
 
an Introduction to Redux
an Introduction to Reduxan Introduction to Redux
an Introduction to Redux
 
Intro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScriptIntro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScript
 
Web technologies-course 12.pptx
Web technologies-course 12.pptxWeb technologies-course 12.pptx
Web technologies-course 12.pptx
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
React.js at Cortex
React.js at CortexReact.js at Cortex
React.js at Cortex
 
ReactJS presentation.pptx
ReactJS presentation.pptxReactJS presentation.pptx
ReactJS presentation.pptx
 
React.js - The Dawn of Virtual DOM
React.js - The Dawn of Virtual DOMReact.js - The Dawn of Virtual DOM
React.js - The Dawn of Virtual DOM
 
React.js - and how it changed our thinking about UI
React.js - and how it changed our thinking about UIReact.js - and how it changed our thinking about UI
React.js - and how it changed our thinking about UI
 
O365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - MaterialO365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - Material
 
[Final] ReactJS presentation
[Final] ReactJS presentation[Final] ReactJS presentation
[Final] ReactJS presentation
 
Workshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareWorkshop 22: React-Redux Middleware
Workshop 22: React-Redux Middleware
 
Workshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux AdvancedWorkshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux Advanced
 
Introduction to Angular JS
Introduction to Angular JSIntroduction to Angular JS
Introduction to Angular JS
 

Mais de FITC

Cut it up
Cut it upCut it up
Cut it upFITC
 
Designing for Digital Health
Designing for Digital HealthDesigning for Digital Health
Designing for Digital HealthFITC
 
Profiling JavaScript Performance
Profiling JavaScript PerformanceProfiling JavaScript Performance
Profiling JavaScript PerformanceFITC
 
Surviving Your Tech Stack
Surviving Your Tech StackSurviving Your Tech Stack
Surviving Your Tech StackFITC
 
How to Pitch Your First AR Project
How to Pitch Your First AR ProjectHow to Pitch Your First AR Project
How to Pitch Your First AR ProjectFITC
 
Start by Understanding the Problem, Not by Delivering the Answer
Start by Understanding the Problem, Not by Delivering the AnswerStart by Understanding the Problem, Not by Delivering the Answer
Start by Understanding the Problem, Not by Delivering the AnswerFITC
 
Cocaine to Carrots: The Art of Telling Someone Else’s Story
Cocaine to Carrots: The Art of Telling Someone Else’s StoryCocaine to Carrots: The Art of Telling Someone Else’s Story
Cocaine to Carrots: The Art of Telling Someone Else’s StoryFITC
 
Everyday Innovation
Everyday InnovationEveryday Innovation
Everyday InnovationFITC
 
HyperLight Websites
HyperLight WebsitesHyperLight Websites
HyperLight WebsitesFITC
 
Everything is Terrifying
Everything is TerrifyingEverything is Terrifying
Everything is TerrifyingFITC
 
Post-Earth Visions: Designing for Space and the Future Human
Post-Earth Visions: Designing for Space and the Future HumanPost-Earth Visions: Designing for Space and the Future Human
Post-Earth Visions: Designing for Space and the Future HumanFITC
 
The Rise of the Creative Social Influencer (and How to Become One)
The Rise of the Creative Social Influencer (and How to Become One)The Rise of the Creative Social Influencer (and How to Become One)
The Rise of the Creative Social Influencer (and How to Become One)FITC
 
East of the Rockies: Developing an AR Game
East of the Rockies: Developing an AR GameEast of the Rockies: Developing an AR Game
East of the Rockies: Developing an AR GameFITC
 
Creating a Proactive Healthcare System
Creating a Proactive Healthcare SystemCreating a Proactive Healthcare System
Creating a Proactive Healthcare SystemFITC
 
World Transformation: The Secret Agenda of Product Design
World Transformation: The Secret Agenda of Product DesignWorld Transformation: The Secret Agenda of Product Design
World Transformation: The Secret Agenda of Product DesignFITC
 
The Power of Now
The Power of NowThe Power of Now
The Power of NowFITC
 
High Performance PWAs
High Performance PWAsHigh Performance PWAs
High Performance PWAsFITC
 
Rise of the JAMstack
Rise of the JAMstackRise of the JAMstack
Rise of the JAMstackFITC
 
From Closed to Open: A Journey of Self Discovery
From Closed to Open: A Journey of Self DiscoveryFrom Closed to Open: A Journey of Self Discovery
From Closed to Open: A Journey of Self DiscoveryFITC
 
Projects Ain’t Nobody Got Time For
Projects Ain’t Nobody Got Time ForProjects Ain’t Nobody Got Time For
Projects Ain’t Nobody Got Time ForFITC
 

Mais de FITC (20)

Cut it up
Cut it upCut it up
Cut it up
 
Designing for Digital Health
Designing for Digital HealthDesigning for Digital Health
Designing for Digital Health
 
Profiling JavaScript Performance
Profiling JavaScript PerformanceProfiling JavaScript Performance
Profiling JavaScript Performance
 
Surviving Your Tech Stack
Surviving Your Tech StackSurviving Your Tech Stack
Surviving Your Tech Stack
 
How to Pitch Your First AR Project
How to Pitch Your First AR ProjectHow to Pitch Your First AR Project
How to Pitch Your First AR Project
 
Start by Understanding the Problem, Not by Delivering the Answer
Start by Understanding the Problem, Not by Delivering the AnswerStart by Understanding the Problem, Not by Delivering the Answer
Start by Understanding the Problem, Not by Delivering the Answer
 
Cocaine to Carrots: The Art of Telling Someone Else’s Story
Cocaine to Carrots: The Art of Telling Someone Else’s StoryCocaine to Carrots: The Art of Telling Someone Else’s Story
Cocaine to Carrots: The Art of Telling Someone Else’s Story
 
Everyday Innovation
Everyday InnovationEveryday Innovation
Everyday Innovation
 
HyperLight Websites
HyperLight WebsitesHyperLight Websites
HyperLight Websites
 
Everything is Terrifying
Everything is TerrifyingEverything is Terrifying
Everything is Terrifying
 
Post-Earth Visions: Designing for Space and the Future Human
Post-Earth Visions: Designing for Space and the Future HumanPost-Earth Visions: Designing for Space and the Future Human
Post-Earth Visions: Designing for Space and the Future Human
 
The Rise of the Creative Social Influencer (and How to Become One)
The Rise of the Creative Social Influencer (and How to Become One)The Rise of the Creative Social Influencer (and How to Become One)
The Rise of the Creative Social Influencer (and How to Become One)
 
East of the Rockies: Developing an AR Game
East of the Rockies: Developing an AR GameEast of the Rockies: Developing an AR Game
East of the Rockies: Developing an AR Game
 
Creating a Proactive Healthcare System
Creating a Proactive Healthcare SystemCreating a Proactive Healthcare System
Creating a Proactive Healthcare System
 
World Transformation: The Secret Agenda of Product Design
World Transformation: The Secret Agenda of Product DesignWorld Transformation: The Secret Agenda of Product Design
World Transformation: The Secret Agenda of Product Design
 
The Power of Now
The Power of NowThe Power of Now
The Power of Now
 
High Performance PWAs
High Performance PWAsHigh Performance PWAs
High Performance PWAs
 
Rise of the JAMstack
Rise of the JAMstackRise of the JAMstack
Rise of the JAMstack
 
From Closed to Open: A Journey of Self Discovery
From Closed to Open: A Journey of Self DiscoveryFrom Closed to Open: A Journey of Self Discovery
From Closed to Open: A Journey of Self Discovery
 
Projects Ain’t Nobody Got Time For
Projects Ain’t Nobody Got Time ForProjects Ain’t Nobody Got Time For
Projects Ain’t Nobody Got Time For
 

Último

VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With RoomVIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Roomdivyansh0kumar0
 
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night StandHot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Standkumarajju5765
 
AlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsAlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsThierry TROUIN ☁
 
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024APNIC
 
Russian Call Girls in Kolkata Ishita 🤌 8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Ishita 🤌  8250192130 🚀 Vip Call Girls KolkataRussian Call Girls in Kolkata Ishita 🤌  8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Ishita 🤌 8250192130 🚀 Vip Call Girls Kolkataanamikaraghav4
 
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With RoomVIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Roomgirls4nights
 
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...APNIC
 
Russian Call Girls in Kolkata Samaira 🤌 8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Samaira 🤌  8250192130 🚀 Vip Call Girls KolkataRussian Call Girls in Kolkata Samaira 🤌  8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Samaira 🤌 8250192130 🚀 Vip Call Girls Kolkataanamikaraghav4
 
Hot Service (+9316020077 ) Goa Call Girls Real Photos and Genuine Service
Hot Service (+9316020077 ) Goa  Call Girls Real Photos and Genuine ServiceHot Service (+9316020077 ) Goa  Call Girls Real Photos and Genuine Service
Hot Service (+9316020077 ) Goa Call Girls Real Photos and Genuine Servicesexy call girls service in goa
 
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779Delhi Call girls
 
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebGDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebJames Anderson
 
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...Sheetaleventcompany
 
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls KolkataLow Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkataanamikaraghav4
 
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.soniya singh
 
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝soniya singh
 

Último (20)

Rohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No AdvanceRohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
 
VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With RoomVIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Room
 
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night StandHot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
 
AlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsAlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with Flows
 
Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...
Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...
Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...
 
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024
 
Russian Call Girls in Kolkata Ishita 🤌 8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Ishita 🤌  8250192130 🚀 Vip Call Girls KolkataRussian Call Girls in Kolkata Ishita 🤌  8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Ishita 🤌 8250192130 🚀 Vip Call Girls Kolkata
 
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With RoomVIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
 
Call Girls In South Ex 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SERVICE
Call Girls In South Ex 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SERVICECall Girls In South Ex 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SERVICE
Call Girls In South Ex 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SERVICE
 
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
 
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...
 
Russian Call Girls in Kolkata Samaira 🤌 8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Samaira 🤌  8250192130 🚀 Vip Call Girls KolkataRussian Call Girls in Kolkata Samaira 🤌  8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Samaira 🤌 8250192130 🚀 Vip Call Girls Kolkata
 
Hot Service (+9316020077 ) Goa Call Girls Real Photos and Genuine Service
Hot Service (+9316020077 ) Goa  Call Girls Real Photos and Genuine ServiceHot Service (+9316020077 ) Goa  Call Girls Real Photos and Genuine Service
Hot Service (+9316020077 ) Goa Call Girls Real Photos and Genuine Service
 
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
 
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebGDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
 
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
 
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls KolkataLow Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
 
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
 
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
 
Rohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No AdvanceRohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
 

Building React Applications with Redux

  • 1.
  • 2. Image by mulad Many people choose to think of React as the V in MVC. – “Why React?” in React documentation “
  • 3. MVC in Theory Image by mulad Model( ͡° ͜ʖ ͡°) View Controller
  • 4. MVC in Practice Image by mulad View Model Model Model Model Model View Model View Model View Model ಠ_ಠ
  • 5. Isolated (“Dumb”) Components Parent Child Props Callbacks Maximize your use of “dumb” components.
  • 6. Advantages of Isolated Components • Helps with code reuse. • Helps with testing. • Makes it easy to reason about your code. Image by mulad
  • 7. Sources of Those Benefits • Dumb components are isolation from the rest of the application. • Dumb components are mostly stateless. Image by mulad
  • 8. Trouble with State • A lot of us were raised on OOP. Objects are stateful. • The effect of calling a method depends on the arguments and the object’s state. • Very painful to test. • Very hard to understand. • Aims to mimic the real world. • But why replicate the unnecessary complexity? Image by mulad
  • 9. Alternative: Pure Functions • The output of a pure function depends only on inputs. • Pure function has no side-effects. • Much easier to understand. • Much easier to test. • Very easy to build through composition. Image by mulad
  • 10. Truly Stateless Components Image by mulad function HelloMessage(props) { return <div>Hello {props.name}</div>; }
  • 11. Even Better Image by mulad const HelloMessage = (props) => <div>Hello {props.name}</div>; Use stateless components whenever you can.
  • 12. Where Does Business Logic Go? • Each component gets props from its parent. • Each component transmits actions to the parent. • Turtles all the way down up? • Top-level components need to be a bit smarter! • We’ll call them “container components”. Image by mulad
  • 13. Linking Containers with Models Image by mulad Container Model ModelContainer Nevermind…
  • 14. Should We Use the Container’s State? • We could, but so much for separation of concerns… Image by mulad
  • 15. What If We Did It the React Way? ??? Container Component Props Callbacks
  • 16. What If We Did It the React Way? State Container Container Component Props Callbacks
  • 17. Flux Architecture State Container Container Component Change events Actions
  • 18. Handling Data in the State Container Component StoreComponent Dispatcher Action
  • 19. Handling Data in the State Container Component Store API, etc. Component Dispatcher Action(s)Action
 Creator We’ll see another
 way of doing this.
  • 20. Redux
  • 21. A Better State Container • https://github.com/rackt/redux • Pretty much the dominant way of doing Flux with React today. • Key concepts: a single store + state “reducers”. • Can a single store be a good idea? • What the heck is a “reducer”?
  • 22. Reducer Functions • Basic reduce(): function addOneValue (value, state) { return state + value; } [1,2,3,4,5].reduce(addOneValue, 0); • Running through the items: 1: 0 => 1 2: 1 => 3 3: 3 => 6 4: 6 => 10 5: 10 => 15
  • 23. Action Reducers in Redux • Take an action and a state, return a new state. • Your app’s state is a reduction over the actions. • Each reducer operates on a subset of the global state. • Simple reducers are combined into complex ones.
  • 24. Creating an Action const UPDATE_NOTE_CONTENT = 'App/UPDATE_NOTE_CONTENT'; function updateNoteContent(noteId, newContent) { return { type: UPDATE_NOTE_CONTENT, payload: { noteId: noteId, newContent: newContent } } }
  • 25. Creating an Action, more ES6 const UPDATE_NOTE_CONTENT = 'App/UPDATE_NOTE_CONTENT'; const updateNoteContent = (noteId, newContent) => ({ type: UPDATE_NOTE_CONTENT, payload: {noteId, newContent} });
  • 26. A Reducer export const notes = createReducer({ [UPDATE_NOTE_CONTENT]: (state, action) => state.setIn( ['byId', action.payload.noteId, 'html'], action.payload.newContent ), [SOME_OTHER_ACTION]: (state, action) => { // do something else or just return state; }), });
  • 27. A Reducer, more ES5ish export const notes = createReducer({ [UPDATE_NOTE_CONTENT]: function (state, action) { return state.setIn( ['byId', action.payload.noteId, 'html'], action.payload.newContent ); }, [SOME_OTHER_ACTION]: function (state, action) { // do something else or just return state; }, });
  • 28. Why Is This a Good Idea? • Reducers are pure functions – easy to understand, easy to test. • Reducers are synchronous. • Data logic is 100% separated from view logic. • You can still have modularity by combining reducers. • New opportunities for tools.
  • 29. How Do We Avoid Mutating State? • Reducers are supposed to not change the old state. But how do we keep them honest? • One option is to clone the object every time. • “Immutable.JS” is the library to use. var newData = data.setIn( ['foo', 'bar', 'baz'], 42 ); • This is a key building block for stateless architecture.
  • 30. The Reducer Example Again export const notes = createReducer({ [UPDATE_NOTE_CONTENT]: (state, action) => state.setIn( ['byId', action.payload.noteId, 'html'], action.payload.newContent ), [SOME_OTHER_ACTION]: (state, action) => { // do something else or just return state; }), });
  • 31. Connecting Container Components import { connect } from 'react-redux'; export default connect( mapStateToProps, mapDispatchToProps, )(MainPage);
  • 32. React-Redux Mapping Functions function mapStateToProps(state) { const notesAsJS = state.notes.toJS(); return { notes: notesAsJS.ordered.map((id) => notesAsJS.byId[id]) }; } function mapDispatchToProps(dispatch) { return { onContentChange: (noteId, newContent) => dispatch(noteActions.updateNoteContent( noteId, newContent)), }; }
  • 33. Handling Asyncronous Actions • Option 1: “Smart” actions creators. • Option 2: Middleware. • Option 2′: React Sagas.
  • 34. Smart Action Creators • Call an action creator to initiate a request. • The action creator emits an action to inform everyone that a request was made. • The action creator makes a request. • If the request succeeds, the action creator emits an action to inform everyone that a request was completed. (Same for failure and timeout.) • The details of interacting with the server should be pushed into a module.
  • 35. An Example, Part 1 function makeFetchNotesAction(status, data) { return { type: FETCH_NOTES, payload: { status: status, data: data } }; }
  • 36. An Example, Part 1 export function fetchNotes() { return dispatch => { dispatch(makeFetchNotesAction('request')); return fetchData() .then(json => dispatch(makeFetchNotesAction('success', json))) .catch(error => dispatch(makeFetchNotesAction('error', error))); }; }
  • 37. Alternatively: Redux Middleware • A middleware is a function that allows you to capture actions and do something before they get to the reducers. • This can include things like API calls. • More generally, the sky is the limit. • Perhaps a little too generic for many cases.
  • 38. Alternative: Redux Sagas • A middleware that works with generators. • Awesome, if you understand generators. • Can simplify complex workflows. • Very new.
  • 39. Redux Sagas Example function* fetchNotesForStack(action) { const stackId = action.payload.stackId; yield put(getNotes.request()); const {data, error} = yield dataApi.getNotesForStack(stackId); if (!error) { yield put(getNotes.success(organizeNotes(data.notes))); } else { yield put(getNotes.failure(error)); } } function* watchFetchNotesForStack() { yield* takeEvery(SELECT_STACK, fetchNotesForStack); }
  • 40. Testing Is Easy describe('on ADD_NOTE', () => { it('should create a new note', () => { const getNoteCount = () => initialState.toJS().ordered.length; const previousCount = getNoteCount(); const newState = notesReducer(initialState, {type: ADD_NOTE}); assert.strictEqual(previousCount + 1, getNoteCount()); const newNoteId = newState.toJS().ordered[0]; const newNoteHtml = newState.getIn(['byId', newNoteId, 'html']); assert.strictEqual(newNoteHtml, 'No content'); }); });
  • 41. Caveats • Its addictive. • You won’t be happy using anything else. • Your friends might not understand your obsession.
  • 42. THANK YOU! Yuri Takhteyev @qaramazov rangle CTO, Rangle.io Some rights reserved - Creative Commons 2.0 by-sa