SlideShare a Scribd company logo
Redux at scale
@matterstech
by Baptiste
@batmansmk
I assume you know
Redux.
20 frontend devs
5 apps desktop, PWA, native
130+ action types / app
Matters is a startup studio
Redux scaled with:
- our team size
- the form factors supported
- the number of features in the apps
This is how we did it.
1/ Planed 1 full day of
training for each member
Official documentation
Videos on Egghead from @dan_abramov
Code
Make a little quizz!
- What is a selector?
- How much RAM does an
immutable state use?
- What is a normalized state?
2/ Tooled our env
const store = createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__()
);
https://github.com/zalmoxisus/redux-devtools-extension
add
3/ Used action
creators
// 1 - Defining in our components got messy.
const action = {type: 'my-app/users/ADD', {id:
1, name:'Bat'}}
3/ Action creators
// 2 - Better in ./users.js
export const addUser = payload => ({type: 'my-
app/users/ADD', payload})
// and get the action in another file
import {addUser} from '../redux/users'
const action = addUser({id: 1, name:'Bat'})
- defines an API
- defines an explicit dependency
component <=> action
- are convenient with react-redux
3/ Action creators
// 1 - instead of
const mapDispatchToProps = dispatch => {
return {
addUser: payload => dispatch({type:'my-app/users/
ADD',payload})
}
}
const connect(null, mapDispatchToProps)(MyComponent)
3/ Actions creators are convenient
// 2 - with action creators
import {addUser} from './redux/users'
const connect(null, {addUser})(MyComponent)
4/ Redux ducks
4/ Redux ducks
const ADD = 'my-app/users/ADD';
export default function reducer(state = {}, action = {})
{
switch (action.type) {
ADD: return {
...state, 

[action.payload.id]: action.payload

}
default: return state;
}
}
// Action Creators
export function addUser(payload) {
return { type: ADD, payload };
}
4/ Redux ducks
Redux ducks is sufficient for us.*
* tested up to our capability.
5/ Write Unit tests
Redux ❤ TDD so much
0
15
30
45
60
without test with tests
dev ut dev maintenance ut maintenance
Mitigated Unit tests ROI in
frontend
Possible causes of bad ROI on automated
testing?
Frontend code changes too often to have good
ROI with systematic Unit Testing.
https://www.future-processing.pl/blog/object-oriented-metrics-by-robert-martin/
0
15
30
45
60
all js no test all js with tests redux only no test redux with tests
dev ut dev maintenance ut maintenance
6/ Use payload-based
actions
export const editName = name => ({type:'users/edit-name',
name});
export const editEmail = email => ({type:'users/edit-email',
email});
// can be often simplified to
export const edit = payload => ({type:’users/edit', payload});
6/ Payload-based actions
With Payload-based actions,
reducers are simpler
7/ Frontend development
is all about side-effects
redux-thunk
didn't scale.
let’s talk about redux-thunk.
Redux co-creator

after he saw
redux-thunk
in our codebase
We were more successful with
redux-sagas.*
* Ask me more details, doesn’t fit in the talk!
8/ Normalized the
state like a db
8/ Normalization
// 1 - instead of
const state = {
users: [
{ id: 1, name: "Alan", groups: [{ name: "Dog" }, { name: "Cat" }] },
{ id: 2, name: "Chloe", groups: { name: "Dog" } },
{ id: 1, name: "Marvis", groups: { name: "Cat" } }
]
};
// 2- Normalize and index by primary key
const state = {
users: {
1: { id: 1, name: "Alan", groups: [1, 2] },
2: { id: 2, name: "Chloe", groups: [1] },
3: { id: 3, name: "Marvis", groups: [2] }
},
groups: {
1: { id: 1, name: “Dog” },
2: { id: 2, name: "Cat" }
}
};
8/ Normalize state
9/ Selectors are
helpful
export const getGroupsById = (state, ids) => ids.map(
id => state.groups[id]
)
export const getUsersWithGroupsById = (state, ids) => ids.map(id
=> ({
...state.users[id],
groups: getGroupsById(state.users[id].groups)
}))
9/ Selectors
10/ Flow and
Typescript helped
1/ Plan 1 day of training
2/ Tool the env
3/ Action creators
4/ Structure in modules
5/ TDD
6/ Payload-based actions
7/ Side-effects are 95% of the problem
8/ Normalize the state
9/ Selectors are helpful
10/ Types
@matterstech
Thanks!
Any questions?

More Related Content

What's hot

Jenkinsプラグインの作り方
Jenkinsプラグインの作り方Jenkinsプラグインの作り方
Jenkinsプラグインの作り方
Kiyotaka Oku
 
Test kitchen 1.0 - Fletcher Nichol
Test kitchen 1.0 - Fletcher NicholTest kitchen 1.0 - Fletcher Nichol
Test kitchen 1.0 - Fletcher Nichol
Devopsdays
 

What's hot (20)

Martin Aspeli Extending And Customising Plone 3
Martin Aspeli   Extending And Customising Plone 3Martin Aspeli   Extending And Customising Plone 3
Martin Aspeli Extending And Customising Plone 3
 
Building JBoss AS 7 for Fedora
Building JBoss AS 7 for FedoraBuilding JBoss AS 7 for Fedora
Building JBoss AS 7 for Fedora
 
Night Watch with QA
Night Watch with QANight Watch with QA
Night Watch with QA
 
Jenkinsプラグインの作り方
Jenkinsプラグインの作り方Jenkinsプラグインの作り方
Jenkinsプラグインの作り方
 
Puppeteer - Headless Chrome Node API
Puppeteer - Headless Chrome Node APIPuppeteer - Headless Chrome Node API
Puppeteer - Headless Chrome Node API
 
Jasmine with JS-Test-Driver
Jasmine with JS-Test-DriverJasmine with JS-Test-Driver
Jasmine with JS-Test-Driver
 
Working Software Over Comprehensive Documentation
Working Software Over Comprehensive DocumentationWorking Software Over Comprehensive Documentation
Working Software Over Comprehensive Documentation
 
Tasting Your First Test Burger
Tasting Your First Test BurgerTasting Your First Test Burger
Tasting Your First Test Burger
 
Frontend SPOF
Frontend SPOFFrontend SPOF
Frontend SPOF
 
Automating your workflow with Gulp.js
Automating your workflow with Gulp.jsAutomating your workflow with Gulp.js
Automating your workflow with Gulp.js
 
Building and Deployment of Drupal sites with Features and Context
Building and Deployment of Drupal sites with Features and ContextBuilding and Deployment of Drupal sites with Features and Context
Building and Deployment of Drupal sites with Features and Context
 
How we maintain 200+ Drupal sites in Georgetown University
How we maintain 200+ Drupal sites in Georgetown UniversityHow we maintain 200+ Drupal sites in Georgetown University
How we maintain 200+ Drupal sites in Georgetown University
 
CI : the first_step: Auto Testing with CircleCI - (MOSG)
CI : the first_step: Auto Testing with CircleCI - (MOSG)CI : the first_step: Auto Testing with CircleCI - (MOSG)
CI : the first_step: Auto Testing with CircleCI - (MOSG)
 
Continuous Integration Testing in Django
Continuous Integration Testing in DjangoContinuous Integration Testing in Django
Continuous Integration Testing in Django
 
Selenium Testing with TestingBot.com
Selenium Testing with TestingBot.comSelenium Testing with TestingBot.com
Selenium Testing with TestingBot.com
 
Auto Build
Auto BuildAuto Build
Auto Build
 
DevOps叢林裡的小隊游擊戰術 (@ iThome DevOps 2015)
DevOps叢林裡的小隊游擊戰術 (@ iThome DevOps 2015)DevOps叢林裡的小隊游擊戰術 (@ iThome DevOps 2015)
DevOps叢林裡的小隊游擊戰術 (@ iThome DevOps 2015)
 
Puppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing ToolPuppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing Tool
 
Test kitchen 1.0 - Fletcher Nichol
Test kitchen 1.0 - Fletcher NicholTest kitchen 1.0 - Fletcher Nichol
Test kitchen 1.0 - Fletcher Nichol
 
Puppeteer
PuppeteerPuppeteer
Puppeteer
 

Similar to 10 tips for Redux at scale

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
 
Day in a life of a node.js developer
Day in a life of a node.js developerDay in a life of a node.js developer
Day in a life of a node.js developer
Edureka!
 

Similar to 10 tips for Redux at scale (20)

React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)
 
7 Redux challenges
7 Redux challenges7 Redux challenges
7 Redux challenges
 
Profiling PHP with Xdebug / Webgrind
Profiling PHP with Xdebug / WebgrindProfiling PHP with Xdebug / Webgrind
Profiling PHP with Xdebug / Webgrind
 
React Native in Production
React Native in ProductionReact Native in Production
React Native in Production
 
Learn react-js
Learn react-jsLearn react-js
Learn react-js
 
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
 
CollabSphere 2021 - DEV114 - The Nuts and Bolts of CI/CD With a Large XPages ...
CollabSphere 2021 - DEV114 - The Nuts and Bolts of CI/CD With a Large XPages ...CollabSphere 2021 - DEV114 - The Nuts and Bolts of CI/CD With a Large XPages ...
CollabSphere 2021 - DEV114 - The Nuts and Bolts of CI/CD With a Large XPages ...
 
One code Web, iOS, Android
One code Web, iOS, AndroidOne code Web, iOS, Android
One code Web, iOS, Android
 
JDD 2017: 7 things which you should care about before release your code to pr...
JDD 2017: 7 things which you should care about before release your code to pr...JDD 2017: 7 things which you should care about before release your code to pr...
JDD 2017: 7 things which you should care about before release your code to pr...
 
Multi-tenancy with Rails
Multi-tenancy with RailsMulti-tenancy with Rails
Multi-tenancy with Rails
 
Testing Big in JavaScript
Testing Big in JavaScriptTesting Big in JavaScript
Testing Big in JavaScript
 
Introduction To Eclipse RCP
Introduction To Eclipse RCPIntroduction To Eclipse RCP
Introduction To Eclipse RCP
 
Joomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven PignataroJoomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven Pignataro
 
Test Drive Development in Ruby On Rails
Test Drive Development in Ruby On RailsTest Drive Development in Ruby On Rails
Test Drive Development in Ruby On Rails
 
Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]
 
JS Fest 2019/Autumn. Влад Федосов. Technology agnostic microservices at SPA f...
JS Fest 2019/Autumn. Влад Федосов. Technology agnostic microservices at SPA f...JS Fest 2019/Autumn. Влад Федосов. Technology agnostic microservices at SPA f...
JS Fest 2019/Autumn. Влад Федосов. Technology agnostic microservices at SPA f...
 
Behavior Driven Development by Example
Behavior Driven Development by ExampleBehavior Driven Development by Example
Behavior Driven Development by Example
 
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
 
Day in a life of a node.js developer
Day in a life of a node.js developerDay in a life of a node.js developer
Day in a life of a node.js developer
 
Day In A Life Of A Node.js Developer
Day In A Life Of A Node.js DeveloperDay In A Life Of A Node.js Developer
Day In A Life Of A Node.js Developer
 

More from inovia

More from inovia (20)

10 essentials steps for kafka streaming services
10 essentials steps for kafka streaming services10 essentials steps for kafka streaming services
10 essentials steps for kafka streaming services
 
Redux at scale
Redux at scaleRedux at scale
Redux at scale
 
DocuSign's Road to react
DocuSign's Road to reactDocuSign's Road to react
DocuSign's Road to react
 
API Gateway: Nginx way
API Gateway: Nginx wayAPI Gateway: Nginx way
API Gateway: Nginx way
 
Kafka: meetup microservice
Kafka: meetup microserviceKafka: meetup microservice
Kafka: meetup microservice
 
Microservice: starting point
Microservice:  starting pointMicroservice:  starting point
Microservice: starting point
 
Correlation id (tid)
Correlation id (tid)Correlation id (tid)
Correlation id (tid)
 
Meetic back end redesign - Meetup microservices
Meetic back end redesign - Meetup microservicesMeetic back end redesign - Meetup microservices
Meetic back end redesign - Meetup microservices
 
Security in microservices architectures
Security in microservices architecturesSecurity in microservices architectures
Security in microservices architectures
 
Building a Secure, Performant Network Fabric for Microservice Applications
Building a Secure, Performant Network Fabric for Microservice ApplicationsBuilding a Secure, Performant Network Fabric for Microservice Applications
Building a Secure, Performant Network Fabric for Microservice Applications
 
Microservices vs SOA
Microservices vs SOAMicroservices vs SOA
Microservices vs SOA
 
CQRS, an introduction by JC Bohin
CQRS, an introduction by JC BohinCQRS, an introduction by JC Bohin
CQRS, an introduction by JC Bohin
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven Design
 
Oauth2, open-id connect with microservices
Oauth2, open-id connect with microservicesOauth2, open-id connect with microservices
Oauth2, open-id connect with microservices
 
You probably don't need microservices
You probably don't need microservicesYou probably don't need microservices
You probably don't need microservices
 
Api Gateway - What's the use of an api gateway?
Api Gateway - What's the use of an api gateway?Api Gateway - What's the use of an api gateway?
Api Gateway - What's the use of an api gateway?
 
Steam Learn: An introduction to Redis
Steam Learn: An introduction to RedisSteam Learn: An introduction to Redis
Steam Learn: An introduction to Redis
 
Steam Learn: Speedrun et TAS
Steam Learn: Speedrun et TASSteam Learn: Speedrun et TAS
Steam Learn: Speedrun et TAS
 
Steam Learn: Asynchronous Javascript
Steam Learn: Asynchronous JavascriptSteam Learn: Asynchronous Javascript
Steam Learn: Asynchronous Javascript
 
Steam Learn: Cheat sheet for Vim
Steam Learn: Cheat sheet for VimSteam Learn: Cheat sheet for Vim
Steam Learn: Cheat sheet for Vim
 

Recently uploaded

Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
Bhaskar Mitra
 

Recently uploaded (20)

Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John Staveley
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
НАДІЯ ФЕДЮШКО БАЦ «Професійне зростання QA спеціаліста»
НАДІЯ ФЕДЮШКО БАЦ  «Професійне зростання QA спеціаліста»НАДІЯ ФЕДЮШКО БАЦ  «Професійне зростання QA спеціаліста»
НАДІЯ ФЕДЮШКО БАЦ «Професійне зростання QA спеціаліста»
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1
 

10 tips for Redux at scale

  • 1. Redux at scale @matterstech by Baptiste @batmansmk
  • 2. I assume you know Redux.
  • 3. 20 frontend devs 5 apps desktop, PWA, native 130+ action types / app
  • 4. Matters is a startup studio
  • 5. Redux scaled with: - our team size - the form factors supported - the number of features in the apps This is how we did it.
  • 6. 1/ Planed 1 full day of training for each member
  • 7. Official documentation Videos on Egghead from @dan_abramov Code
  • 8. Make a little quizz! - What is a selector? - How much RAM does an immutable state use? - What is a normalized state?
  • 10. const store = createStore( reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() ); https://github.com/zalmoxisus/redux-devtools-extension
  • 11. add
  • 13. // 1 - Defining in our components got messy. const action = {type: 'my-app/users/ADD', {id: 1, name:'Bat'}} 3/ Action creators // 2 - Better in ./users.js export const addUser = payload => ({type: 'my- app/users/ADD', payload}) // and get the action in another file import {addUser} from '../redux/users' const action = addUser({id: 1, name:'Bat'})
  • 14. - defines an API - defines an explicit dependency component <=> action - are convenient with react-redux 3/ Action creators
  • 15. // 1 - instead of const mapDispatchToProps = dispatch => { return { addUser: payload => dispatch({type:'my-app/users/ ADD',payload}) } } const connect(null, mapDispatchToProps)(MyComponent) 3/ Actions creators are convenient // 2 - with action creators import {addUser} from './redux/users' const connect(null, {addUser})(MyComponent)
  • 18. const ADD = 'my-app/users/ADD'; export default function reducer(state = {}, action = {}) { switch (action.type) { ADD: return { ...state, 
 [action.payload.id]: action.payload
 } default: return state; } } // Action Creators export function addUser(payload) { return { type: ADD, payload }; } 4/ Redux ducks
  • 19. Redux ducks is sufficient for us.* * tested up to our capability.
  • 20. 5/ Write Unit tests
  • 21. Redux ❤ TDD so much
  • 22. 0 15 30 45 60 without test with tests dev ut dev maintenance ut maintenance Mitigated Unit tests ROI in frontend
  • 23. Possible causes of bad ROI on automated testing? Frontend code changes too often to have good ROI with systematic Unit Testing. https://www.future-processing.pl/blog/object-oriented-metrics-by-robert-martin/
  • 24. 0 15 30 45 60 all js no test all js with tests redux only no test redux with tests dev ut dev maintenance ut maintenance
  • 26. export const editName = name => ({type:'users/edit-name', name}); export const editEmail = email => ({type:'users/edit-email', email}); // can be often simplified to export const edit = payload => ({type:’users/edit', payload}); 6/ Payload-based actions
  • 28. 7/ Frontend development is all about side-effects
  • 30. Redux co-creator
 after he saw redux-thunk in our codebase
  • 31. We were more successful with redux-sagas.* * Ask me more details, doesn’t fit in the talk!
  • 34.
  • 35. // 1 - instead of const state = { users: [ { id: 1, name: "Alan", groups: [{ name: "Dog" }, { name: "Cat" }] }, { id: 2, name: "Chloe", groups: { name: "Dog" } }, { id: 1, name: "Marvis", groups: { name: "Cat" } } ] }; // 2- Normalize and index by primary key const state = { users: { 1: { id: 1, name: "Alan", groups: [1, 2] }, 2: { id: 2, name: "Chloe", groups: [1] }, 3: { id: 3, name: "Marvis", groups: [2] } }, groups: { 1: { id: 1, name: “Dog” }, 2: { id: 2, name: "Cat" } } }; 8/ Normalize state
  • 37. export const getGroupsById = (state, ids) => ids.map( id => state.groups[id] ) export const getUsersWithGroupsById = (state, ids) => ids.map(id => ({ ...state.users[id], groups: getGroupsById(state.users[id].groups) })) 9/ Selectors
  • 39. 1/ Plan 1 day of training 2/ Tool the env 3/ Action creators 4/ Structure in modules 5/ TDD 6/ Payload-based actions 7/ Side-effects are 95% of the problem 8/ Normalize the state 9/ Selectors are helpful 10/ Types