SlideShare a Scribd company logo
Reduxing
Like a pro!
Boris Dinkevich boris@500tech.com
WHAT WILL WE LEARN?
1. Cool stuff
2. Lots of cool libraries
TOOLS
https://github.com/markerikson/redux-ecosystem-links
Boris Dinkevich
- 4 years Dev Ops
- 4 years Embedded C
- 4 years Ruby on Rails
- 4 years JavaScript (Angular/React)
Developing stuff
Middleware
MIDDLEWARE?
Middleware skeleton
function myMiddleware({ dispatch, getState }) {

return function(next) {

return function(action) {

return next(action);

}

}

}
Middleware skeleton
const myMiddleware = ({ dispatch }) => next => action => {

return next(action);

}
How long do actions take?
const benchmarkMiddleware = store => next => action => {

console.time(action.type);

next(action);

console.timeEnd(action.type);

};
> SET_USER: 0.645ms
Analytics
const analyticsMiddleware = () => next => action => {
const { analytics }= (action.meta || {});
next(action);
if (analytics) {
ga(analytics);
clickTable(analytics);
}
};
const addTodo = (name) => ({
type: ADD_TODO,
…
meta: {
analytics: 'add todo'
}
});
Auto Complete
dispatch(autoComplete('b')); // => 100ms: 1000 items
dispatch(autoComplete('bo')); // => 70ms: 70 items
dispatch(autoComplete('bor')); // => 3ms: 2 items
const autoComplete = (string) => ({
type: AUTO_COMPLETE,
payload: string,
meta: {
debounce: 500
}
});
API
REDUX THUNK?
Async Action Creators


const fetchUsers = () => (dispatch, getState) => {



};
Async Action Creators


const fetchUsers = () => (dispatch, getState) => {

// Get headers (like auth) from state

// Calc URL 

// etc

fetch(BASE_URL + ‘/users’).then(

(data) => dispatch(setUsers(data)),

(error) => console.log(error)

);

};
Async Action Creators


const fetchUsers = () => (dispatch, getState) => {

// Get headers (like auth) from state

// Calc URL 

// etc

fetch(BASE_URL + ‘/users’).then(

(data) => dispatch(setUsers(data)),

(error) => console.log(error)

);

};
const fetchComments = () => (dispatch, getState) => {



};
Async Action Creators


const fetchUsers = () => (dispatch, getState) => {

// Get headers (like auth) from state

// Calc URL 

// etc

fetch(BASE_URL + ‘/users’).then(

(data) => dispatch(setUsers(data)),

(error) => console.log(error)

);

};
const fetchComments = () => (dispatch, getState) => {

// Get headers (like auth) from state

// Calc URL

// etc

fetch(BASE_URL + ‘/comments’).then(

(data) => dispatch(setComments(data)),

(error) => console.log(error)

);

};
Async Action Creators


const fetchUsers = () => (dispatch, getState) => {

// Get headers (like auth) from state

// Calc URL 

// etc

fetch(BASE_URL + ‘/users’).then(

(data) => dispatch(setUsers(data)),

(error) => console.log(error)

);

};
const fetchComments = () => (dispatch, getState) => {

// Get headers (like auth) from state

// Calc URL

// etc

fetch(BASE_URL + ‘/comments’).then(

(data) => dispatch(setComments(data)),

(error) => console.log(error)

);

};
Async Action Creators


const fetchUsers = () => (dispatch, getState) => {

// Get headers (like auth) from state

// Calc URL 

// etc

fetch(BASE_URL + ‘/users’).then(

(data) => dispatch(setUsers(data)),

(error) => console.log(error)

);

};
Async Action Creators


const fetchUsers = () => (dispatch, getState) => {

// Get headers (like auth) from state

// Calc URL 

// etc

fetch(BASE_URL + ‘/users’).then(

(data) => dispatch(setUsers(data)),

(error) => console.log(error)

);

};
const fetchUsers = () => ({
type: API,
payload: {
url: '/users',
success: setUsers
}
});
Async Action Creators


const fetchUsers = () => (dispatch, getState) => {

// Get headers (like auth) from state

// Calc URL 

// etc

fetch(BASE_URL + ‘/users’).then(

(data) => dispatch(setUsers(data)),

(error) => console.log(error)

);

};
const fetchUsers = () => ({
type: API,
payload: {
url: '/users',
success: setUsers
}
});
Middleware
const apiMiddleware = ({ dispatch }) => next => action => {
};
Middleware
const apiMiddleware = ({ dispatch }) => next => action => {
if (action.type !== API) return next(action);
// Do something!
};
Middleware
const apiMiddleware = ({ dispatch }) => next => action => {
if (action.type !== API) return next(action);
const { url, success } = action.payload;
return fetch(BASE_URL + url)
.then(response => response.json())
.then(payload => dispatch({ type: success, payload }));
};
Middleware
const apiMiddleware = ({ dispatch }) => next => action => {
if (action.type !== API) return next(action);
const { url, success } = action.payload;
return fetch(BASE_URL + url)
.then(response => response.json())
.then(payload => dispatch({ type: success, payload }))
.catch(error => dispatch({ type: API_ERROR, error }));
};
SYNC Action Creators
const fetchUsers = () => ({
type: API,
payload: {
url: '/users',
success: setUsers
}
});
const fetchComments = () => ({
type: API,
payload: {
url: '/comments',
success: setComments
}
});
API With Params
const fetchUser = (id) => ({
type: API,
payload: {
url: `/users/${ id }`,
success: setUser
}
});
API POST
const updateUser = (id, data) => ({
type: API,
payload: {
method: 'UPDATE',
url: `/users/${ id }`,
data
}
});
const deleteComment = (id) => ({
type: API,
payload: {
method: 'DELETE',
url: `/comments/${ id }`
}
});
Middleware + Auth
const apiMiddleware = ({ dispatch, getState }) => next => action => {
if (action.type !== API) return next(action);
const { url, success } = action.payload;
return fetch(BASE_URL + url)
.then(response => response.json())
.then(payload => dispatch({ type: success, payload }))
.catch(error => dispatch({ type: API_ERROR, error }));
};
Middleware + Auth
const apiMiddleware = ({ dispatch, getState }) => next => action => {
if (action.type !== API) return next(action);
const { url, success } = action.payload;
const { authToken } = getState().user;
if (authToken) {
// Set headers
}
return fetch(BASE_URL + url)
.then(response => response.json())
.then(payload => dispatch({ type: success, payload }))
.catch(error => dispatch({ type: API_ERROR, error }));
};
API With Params
const fetchUsers = () => ({
type: API,
payload: {
url: '/users',
success: setUsers,
preProcess: preProcessIncomingData,
customSpinner: 'users',
error: customErrorHandler,
timeout: 5000,
useAuth: false
}
});
Testing?
const fetchUsers = () => ({
type: API,
payload: {
url: '/users',
success: setUsers,
preProcess: preProcessIncomingData,
customSpinner: 'users',
error: customErrorHandler,
timeout: 5000,
useAuth: false
}
});
Reducer Action Middleware
State partial with thunk ✓
Dispatch - with thunk ✓
Mutate Action - - ✓
Cancel Action - - ✓
POWER!
Why is that cool?
Dude where is my logic?
Oh right, middleware
SUMMARY
https://redux-book.com
The Complete Redux Book
And read our blog:
http://blog.500tech.com
Keep calm, Redux
@BorisDinkevich / boris@500Tech.com

More Related Content

What's hot

Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
Evan Schultz
 
JavaScript Testing for Rubyists
JavaScript Testing for RubyistsJavaScript Testing for Rubyists
JavaScript Testing for Rubyists
Jamie Dyer
 
Reactive.architecture.with.Angular
Reactive.architecture.with.AngularReactive.architecture.with.Angular
Reactive.architecture.with.Angular
Evan Schultz
 

What's hot (20)

Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
 
React on es6+
React on es6+React on es6+
React on es6+
 
Why Redux-Observable?
Why Redux-Observable?Why Redux-Observable?
Why Redux-Observable?
 
Getting started with ReactJS
Getting started with ReactJSGetting started with ReactJS
Getting started with ReactJS
 
Redux vs Alt
Redux vs AltRedux vs Alt
Redux vs Alt
 
Designing applications with Redux
Designing applications with ReduxDesigning applications with Redux
Designing applications with Redux
 
Angular server-side communication
Angular server-side communicationAngular server-side communication
Angular server-side communication
 
Promise pattern
Promise patternPromise pattern
Promise pattern
 
Switch to React.js from AngularJS developer
Switch to React.js from AngularJS developerSwitch to React.js from AngularJS developer
Switch to React.js from AngularJS developer
 
Avoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAvoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promises
 
Redux training
Redux trainingRedux training
Redux training
 
Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.js
 
Angular mix chrisnoring
Angular mix chrisnoringAngular mix chrisnoring
Angular mix chrisnoring
 
Modern Web Developement
Modern Web DevelopementModern Web Developement
Modern Web Developement
 
JavaScript Testing for Rubyists
JavaScript Testing for RubyistsJavaScript Testing for Rubyists
JavaScript Testing for Rubyists
 
Reactive.architecture.with.Angular
Reactive.architecture.with.AngularReactive.architecture.with.Angular
Reactive.architecture.with.Angular
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
 
Creating a WYSIWYG Editor with React
Creating a WYSIWYG Editor with ReactCreating a WYSIWYG Editor with React
Creating a WYSIWYG Editor with React
 
React with Redux
React with ReduxReact with Redux
React with Redux
 
New improvements for web developers - frontend.fi, Helsinki
New improvements for web developers - frontend.fi, HelsinkiNew improvements for web developers - frontend.fi, Helsinki
New improvements for web developers - frontend.fi, Helsinki
 

Similar to Reduxing like a pro

Emberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applicationsEmberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applications
ColdFusionConference
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
Ting Lv
 

Similar to Reduxing like a pro (20)

Express JS
Express JSExpress JS
Express JS
 
Nodejs do teste de unidade ao de integração
Nodejs  do teste de unidade ao de integraçãoNodejs  do teste de unidade ao de integração
Nodejs do teste de unidade ao de integração
 
Node.js server-side rendering
Node.js server-side renderingNode.js server-side rendering
Node.js server-side rendering
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019
 
Mashing up JavaScript
Mashing up JavaScriptMashing up JavaScript
Mashing up JavaScript
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015
 
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsMashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Server side data sync for mobile apps with silex
Server side data sync for mobile apps with silexServer side data sync for mobile apps with silex
Server side data sync for mobile apps with silex
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Quick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase ServerQuick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase Server
 
How To Manage API Request with AXIOS on a React Native App
How To Manage API Request with AXIOS on a React Native AppHow To Manage API Request with AXIOS on a React Native App
How To Manage API Request with AXIOS on a React Native App
 
Emberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applicationsEmberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applications
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
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.
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in Swift
 

Recently uploaded

AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
Alluxio, Inc.
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
mbmh111980
 

Recently uploaded (20)

Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
 
GraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysisGraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysis
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
 
iGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockiGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by Skilrock
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
AI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in MichelangeloAI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in Michelangelo
 
Studiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting softwareStudiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting software
 
Crafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationCrafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM Integration
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
 

Reduxing like a pro

  • 1. Reduxing Like a pro! Boris Dinkevich boris@500tech.com
  • 2. WHAT WILL WE LEARN? 1. Cool stuff 2. Lots of cool libraries
  • 4. Boris Dinkevich - 4 years Dev Ops - 4 years Embedded C - 4 years Ruby on Rails - 4 years JavaScript (Angular/React) Developing stuff
  • 5.
  • 8. Middleware skeleton function myMiddleware({ dispatch, getState }) {
 return function(next) {
 return function(action) {
 return next(action);
 }
 }
 }
  • 9. Middleware skeleton const myMiddleware = ({ dispatch }) => next => action => {
 return next(action);
 }
  • 10. How long do actions take? const benchmarkMiddleware = store => next => action => {
 console.time(action.type);
 next(action);
 console.timeEnd(action.type);
 }; > SET_USER: 0.645ms
  • 11. Analytics const analyticsMiddleware = () => next => action => { const { analytics }= (action.meta || {}); next(action); if (analytics) { ga(analytics); clickTable(analytics); } }; const addTodo = (name) => ({ type: ADD_TODO, … meta: { analytics: 'add todo' } });
  • 12. Auto Complete dispatch(autoComplete('b')); // => 100ms: 1000 items dispatch(autoComplete('bo')); // => 70ms: 70 items dispatch(autoComplete('bor')); // => 3ms: 2 items const autoComplete = (string) => ({ type: AUTO_COMPLETE, payload: string, meta: { debounce: 500 } });
  • 13. API
  • 15. Async Action Creators 
 const fetchUsers = () => (dispatch, getState) => {
 
 };
  • 16. Async Action Creators 
 const fetchUsers = () => (dispatch, getState) => {
 // Get headers (like auth) from state
 // Calc URL 
 // etc
 fetch(BASE_URL + ‘/users’).then(
 (data) => dispatch(setUsers(data)),
 (error) => console.log(error)
 );
 };
  • 17. Async Action Creators 
 const fetchUsers = () => (dispatch, getState) => {
 // Get headers (like auth) from state
 // Calc URL 
 // etc
 fetch(BASE_URL + ‘/users’).then(
 (data) => dispatch(setUsers(data)),
 (error) => console.log(error)
 );
 }; const fetchComments = () => (dispatch, getState) => {
 
 };
  • 18. Async Action Creators 
 const fetchUsers = () => (dispatch, getState) => {
 // Get headers (like auth) from state
 // Calc URL 
 // etc
 fetch(BASE_URL + ‘/users’).then(
 (data) => dispatch(setUsers(data)),
 (error) => console.log(error)
 );
 }; const fetchComments = () => (dispatch, getState) => {
 // Get headers (like auth) from state
 // Calc URL
 // etc
 fetch(BASE_URL + ‘/comments’).then(
 (data) => dispatch(setComments(data)),
 (error) => console.log(error)
 );
 };
  • 19. Async Action Creators 
 const fetchUsers = () => (dispatch, getState) => {
 // Get headers (like auth) from state
 // Calc URL 
 // etc
 fetch(BASE_URL + ‘/users’).then(
 (data) => dispatch(setUsers(data)),
 (error) => console.log(error)
 );
 }; const fetchComments = () => (dispatch, getState) => {
 // Get headers (like auth) from state
 // Calc URL
 // etc
 fetch(BASE_URL + ‘/comments’).then(
 (data) => dispatch(setComments(data)),
 (error) => console.log(error)
 );
 };
  • 20. Async Action Creators 
 const fetchUsers = () => (dispatch, getState) => {
 // Get headers (like auth) from state
 // Calc URL 
 // etc
 fetch(BASE_URL + ‘/users’).then(
 (data) => dispatch(setUsers(data)),
 (error) => console.log(error)
 );
 };
  • 21. Async Action Creators 
 const fetchUsers = () => (dispatch, getState) => {
 // Get headers (like auth) from state
 // Calc URL 
 // etc
 fetch(BASE_URL + ‘/users’).then(
 (data) => dispatch(setUsers(data)),
 (error) => console.log(error)
 );
 }; const fetchUsers = () => ({ type: API, payload: { url: '/users', success: setUsers } });
  • 22. Async Action Creators 
 const fetchUsers = () => (dispatch, getState) => {
 // Get headers (like auth) from state
 // Calc URL 
 // etc
 fetch(BASE_URL + ‘/users’).then(
 (data) => dispatch(setUsers(data)),
 (error) => console.log(error)
 );
 }; const fetchUsers = () => ({ type: API, payload: { url: '/users', success: setUsers } });
  • 23. Middleware const apiMiddleware = ({ dispatch }) => next => action => { };
  • 24. Middleware const apiMiddleware = ({ dispatch }) => next => action => { if (action.type !== API) return next(action); // Do something! };
  • 25. Middleware const apiMiddleware = ({ dispatch }) => next => action => { if (action.type !== API) return next(action); const { url, success } = action.payload; return fetch(BASE_URL + url) .then(response => response.json()) .then(payload => dispatch({ type: success, payload })); };
  • 26. Middleware const apiMiddleware = ({ dispatch }) => next => action => { if (action.type !== API) return next(action); const { url, success } = action.payload; return fetch(BASE_URL + url) .then(response => response.json()) .then(payload => dispatch({ type: success, payload })) .catch(error => dispatch({ type: API_ERROR, error })); };
  • 27. SYNC Action Creators const fetchUsers = () => ({ type: API, payload: { url: '/users', success: setUsers } }); const fetchComments = () => ({ type: API, payload: { url: '/comments', success: setComments } });
  • 28. API With Params const fetchUser = (id) => ({ type: API, payload: { url: `/users/${ id }`, success: setUser } });
  • 29. API POST const updateUser = (id, data) => ({ type: API, payload: { method: 'UPDATE', url: `/users/${ id }`, data } }); const deleteComment = (id) => ({ type: API, payload: { method: 'DELETE', url: `/comments/${ id }` } });
  • 30. Middleware + Auth const apiMiddleware = ({ dispatch, getState }) => next => action => { if (action.type !== API) return next(action); const { url, success } = action.payload; return fetch(BASE_URL + url) .then(response => response.json()) .then(payload => dispatch({ type: success, payload })) .catch(error => dispatch({ type: API_ERROR, error })); };
  • 31. Middleware + Auth const apiMiddleware = ({ dispatch, getState }) => next => action => { if (action.type !== API) return next(action); const { url, success } = action.payload; const { authToken } = getState().user; if (authToken) { // Set headers } return fetch(BASE_URL + url) .then(response => response.json()) .then(payload => dispatch({ type: success, payload })) .catch(error => dispatch({ type: API_ERROR, error })); };
  • 32. API With Params const fetchUsers = () => ({ type: API, payload: { url: '/users', success: setUsers, preProcess: preProcessIncomingData, customSpinner: 'users', error: customErrorHandler, timeout: 5000, useAuth: false } });
  • 33. Testing? const fetchUsers = () => ({ type: API, payload: { url: '/users', success: setUsers, preProcess: preProcessIncomingData, customSpinner: 'users', error: customErrorHandler, timeout: 5000, useAuth: false } });
  • 34. Reducer Action Middleware State partial with thunk ✓ Dispatch - with thunk ✓ Mutate Action - - ✓ Cancel Action - - ✓ POWER!
  • 35. Why is that cool? Dude where is my logic? Oh right, middleware
  • 38. And read our blog: http://blog.500tech.com Keep calm, Redux @BorisDinkevich / boris@500Tech.com