SlideShare a Scribd company logo
1 of 50
Download to read offline
SELECTORS and
NORMALIZING STATE SHAPE
Improving performance in Redux
Muntasir Chowdhury
mapStateToProps()
const mapStateToProps = state => {
return {
attributeOne: state.attributeOne,
attributeTwo: state.attributeTwo,
};
}
mapStateToProps()
1. Runs when any part of the Redux store updates
2. Shallow compare of computed values (previous and new)
Shallow Compare
Render Do nothing
Not equal Equal
What is a selector?
What is a selector?
Code that derives data
mapStateToProps = state => ( { articles: state.articles });
A simple selector
mapStateToProps = state => ( {
firstThreeArticles: state.articles.splice(0, 3)
});
Transform Data
function getFirstThreeArticles(state) {
return state.articles.slice(0, 3);
}
mapStateToProps = state => ( {
firstThreeArticles: getFirstThreeArticles(state)
});
Extract to function
Adding complexity
function filterArticles(articles, filter) {
switch(filter) {
“SHOW_ALL”:
return articles;
“UNREAD”:
return articles.filter(a => a.unread);
“READ”:
return articles.filter(a => !a.unread);
}
}
mapStateToProps = state => ( {
articles: filterArticles(state.articles, state.filter)
});
function filterArticles(articles, filter) {
switch(filter) {
“SHOW_ALL”:
return articles;
“UNREAD”:
return articles.filter(a => a.unread);
“READ”:
return articles.filter(a => !a.unread);
}
}
mapStateToProps = state => ( {
articles: filterArticles(state.articles, state.filter),
usersOnline: state.usersOnline
});
Redundant derivations
function filterArticles(articles, filter) {
switch(filter) {
“SHOW_ALL”:
return articles;
“UNREAD”:
return articles.filter(a => a.unread);
“READ”:
return articles.filter(a => !a.unread);
}
}
mapStateToProps = state => ( {
articles: filterArticles(state.articles, state.filter),
usersOnline: state.usersOnline
});
state = {
articles: [......],
filter: "UNREAD",
usersOnline: 1629
}
function filterArticles(articles, filter) {
switch(filter) {
“SHOW_ALL”:
return articles;
“UNREAD”:
return articles.filter(a => a.unread);
“READ”:
return articles.filter(a => !a.unread);
}
}
mapStateToProps = state => ( {
articles: filterArticles(state.articles, state.filter),
usersOnline: state.usersOnline
});
state = {
articles: [......],
filter: "UNREAD",
usersOnline: 1629
}
state = {
articles: [......],
filter: "UNREAD",
usersOnline: 2004
}
Memoized Selectors
Reselector
createSelector( )
createSelector( [selector1, selector2...], transformFunction)
function filterArticles(articles, filter) {
switch(filter) {
“SHOW_ALL”:
return articles;
“UNREAD”:
return articles.filter(a => a.unread);
“READ”:
return articles.filter(a => !a.unread);
}
}
mapStateToProps = state => ( {
articles: filterArticles(state.articles, state.filter),
usersOnline: state.usersOnline
});
import { createSelector } from 'reselect'
const getFilter = (state) => state.filter;
const getArticles = (state) => state.articles;
export const filterArticles = createSelector(
[ getFilter, getArticles ],
(articles, filter) => {
switch(filter) {
“SHOW_ALL”:
return articles;
“UNREAD”:
return articles.filter(a => a.unread);
“READ”:
return articles.filter(a => !a.unread);
}
}
)
Connect Selector to Redux Store
import { connect } from 'react-redux';
import Articles from '../components/TodoList';
import { filterArticles } from '../selectors';
 
const mapStateToProps = state => {
return {
articles: filterArticles(state),
usersOnline: state.usersOnline
}
}
  
const ArticleList = connect(mapStateToProps, null)(Articles)
 
export default ArticleList
NORMALIZING STATE SHAPE
Nested State vs
Normalized State
Nested State
const articles = [
{
id : "artcle1",
user : {userId: “ui1”, username : "user1", name : "User 1"},
body : "......",
comments : [
{
id : "comment1",
user : {userId: "ui2", username : "user2", name : "User 2"},
comment : ".....",
},
{
id : "comment2",
user : {userId: "ui3", username : "user3", name : "User 3"},
comment : ".....",
}
]
},
Nested State
{
id : "article2",
user : {username : "user2", name : "User 2"},
body : "......",
comments : [
{
id : "comment3",
user : {userId: "ui3", username : "user3", name : "User 3"},
comment : ".....",
},
{
id : "comment4",
user : {userId: "ui1", username : "user1", name : "User 1"},
comment : ".....",
}
]
}
……
];
Nested State
//articleListContainer.js
mapStateToProps = (state) => ({
articles: state.articles
});
// articleList.js
const ArticleList = (articles) => ({
articles.map(article => <Article article=article />)
});
Selecting Nested State
// article.js
const Article = (article) => ({
<div>article.content</div>
{ article.comments.forEach(comments) => <Comment comment=comment /> }
});
// comment.js
const Comment = (comment) => ({
<div>comment.content</div>
<User user=comment.user />
});
Selecting Nested State
// user.js
const User = (user) => ({
<div>user.name</div>
});
Selecting Nested State
ArticleList
Article
Comment
User
User
Comment …..
Article …..
ArticleList
Article
Comment
User
User
Comment …..
Article …..
Redux Storeconnect()
//action.js
function changeUserName(userId, name) {
return {
type: CHANGE_USER_NAME,
payload: {
name
}
};
}
Updating Nested State
//reducer.js
const posts = (state, action) => {
switch(action.type) {
case "CHANGE_USER_NAME":
// find every post
// where the user as the author of the post
// or as the author of one of its comments
}
}
Updating Nested State
1. Difficult to update
a. Duplicate data
b. Complex reducer logic due to nesting
2. Higher chance of redundant re-renders
Nested State
Normalized State
Divide & Flatten
//articles_reducer.js
articles : {
byId : {
"article1" : {
id : "article1",
user : "user1",
body : "......",
comments : ["comment1", "comment2"]
},
"article2" : {
id : "article2",
user : "user2",
body : "......",
comments : ["comment3", "comment4", "comment5"]
}
},
allIds : ["article1", "article2"]
}
Normalized State
//comments_reducer.js
comments : {
byId : {
"comment1" : {
id : "comment1",
user : "user2",
comment : ".....",
},
"comment2" : {
id : "comment2",
user : "user3",
comment : ".....",
},
"comment3" : {
id : "comment3",
user : "user3",
comment : ".....",
}
},
allIds : ["comment1", "comment2", "comment3"]
}
Normalized State
//users_reducer.js
users : {
byId : {
"user1" : {
username : "user1",
name : "User 1",
}
"user2" : {
username : "user2",
name : "User 2",
}
"user3" : {
username : "user3",
name : "User 3",
}
},
allIds : ["user1", "user2", "user3"]
}
Normalized State
//articleListContainer.js
mapStateToProps = (state) => ({
articles: state.articles.allIds
});
// articleList.js
const ArticleList = (articleIds) => ({
articles.map(articleId => <Article articleId=articleId />)
});
Selecting Normalized State
// article.js
const Article = (article) => ({
<div>article.content</div>
{ article.comments.map(commentIds => <CommentContainer commentId=commentId /> }
});
Selecting Normalized State
Selecting Normalized State
//commentContainer.js
mapStateToProps = (state, ownProps) => ({
comment: state.comments.byId[ownProps.commentId]
});
// comment.js
const Comment = (comment) => ({
<div>comment.content</div>
<UserContainer user=comment.user />
});
Selecting Normalized State
//userContainer.js
mapStateToProps = (state, ownProps) => ({
user: state.user.byId[ownProps.userId]
});
// user.js
const User = (user) => ({
<div>user.name</div>
});
ArticleList
Article
Comment
User
User
Comment …..
Article …..
ArticleList
Article
Comment
User
User
Comment …..
Article …..
Redux Storeconnect()
connect()
connect()
connect()
//action.js
function changeUserName(userId, name) {
return {
type: CHANGE_USER_NAME,
payload: {
name
}
};
}
Updating Normalized
State
//userReducer.js
const usersById = (state, action) => {
switch(action.type) {
case "CHANGE_USER_NAME":
userId = action.payload.id;
changedUser = {
...state[userId],
name: action.payload.name
};
return {
...state,
[userId] : changedUser
};
default:
return state;
}
}
const usersReducer = combineReducers({
byId: usersById,
allIds: [....]
});
Updating Normalized State
Normalized State
1. Easy to update
a. Single copy of data
b. Reducer logic more manageable (less nesting)
2. More connected & independent components -> less re-renders
Other Topics
● Multiple instances of memoized selectors
● Relationships and Tables (treating Redux like a relational DB)
● Normalizing nested data from API using Normalizr
QUESTIONS

More Related Content

What's hot

TDD in the wild
TDD in the wildTDD in the wild
TDD in the wildBrainhub
 
Funcitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional WayFuncitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional WayNatasha Murashev
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF Luc Bors
 
classes & objects in cpp overview
classes & objects in cpp overviewclasses & objects in cpp overview
classes & objects in cpp overviewgourav kottawar
 
A evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no androidA evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no androidRodrigo de Souza Castro
 
Advanced java practical semester 6_computer science
Advanced java practical semester 6_computer scienceAdvanced java practical semester 6_computer science
Advanced java practical semester 6_computer scienceNiraj Bharambe
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginnersDivakar Gu
 
Building android apps with kotlin
Building android apps with kotlinBuilding android apps with kotlin
Building android apps with kotlinShem Magnezi
 
Deep Dive into React Hooks
Deep Dive into React HooksDeep Dive into React Hooks
Deep Dive into React HooksFelix Kühl
 
Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...go_oh
 
Zhongl scala summary
Zhongl scala summaryZhongl scala summary
Zhongl scala summarylunfu zhong
 
Design Patterns Reconsidered
Design Patterns ReconsideredDesign Patterns Reconsidered
Design Patterns ReconsideredAlex Miller
 
CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...
CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...
CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...Mail.ru Group
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기Arawn Park
 

What's hot (20)

TDD in the wild
TDD in the wildTDD in the wild
TDD in the wild
 
Funcitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional WayFuncitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional Way
 
Road to react hooks
Road to react hooksRoad to react hooks
Road to react hooks
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScript
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF
 
greenDAO
greenDAOgreenDAO
greenDAO
 
Sequelize
SequelizeSequelize
Sequelize
 
classes & objects in cpp overview
classes & objects in cpp overviewclasses & objects in cpp overview
classes & objects in cpp overview
 
A evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no androidA evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no android
 
Django - sql alchemy - jquery
Django - sql alchemy - jqueryDjango - sql alchemy - jquery
Django - sql alchemy - jquery
 
Advanced java practical semester 6_computer science
Advanced java practical semester 6_computer scienceAdvanced java practical semester 6_computer science
Advanced java practical semester 6_computer science
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 
Building android apps with kotlin
Building android apps with kotlinBuilding android apps with kotlin
Building android apps with kotlin
 
Deep Dive into React Hooks
Deep Dive into React HooksDeep Dive into React Hooks
Deep Dive into React Hooks
 
Ajax chap 5
Ajax chap 5Ajax chap 5
Ajax chap 5
 
Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...
 
Zhongl scala summary
Zhongl scala summaryZhongl scala summary
Zhongl scala summary
 
Design Patterns Reconsidered
Design Patterns ReconsideredDesign Patterns Reconsidered
Design Patterns Reconsidered
 
CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...
CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...
CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기
 

Similar to Selectors and normalizing state shape

Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]Devon Bernard
 
Data normalization &amp; memoized denormalization
Data normalization &amp; memoized denormalizationData normalization &amp; memoized denormalization
Data normalization &amp; memoized denormalizationSalsita Software
 
Using Array Approach, Linked List approach, and Delete Byte Approach.pdf
Using Array Approach, Linked List approach, and Delete Byte Approach.pdfUsing Array Approach, Linked List approach, and Delete Byte Approach.pdf
Using Array Approach, Linked List approach, and Delete Byte Approach.pdffms12345
 
Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3 Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3 DreamLab
 
SE2016 Android Mikle Anokhin "Speed up application development with data bind...
SE2016 Android Mikle Anokhin "Speed up application development with data bind...SE2016 Android Mikle Anokhin "Speed up application development with data bind...
SE2016 Android Mikle Anokhin "Speed up application development with data bind...Inhacking
 
Going Native: Leveraging the New JSON Native Datatype in Oracle 21c
Going Native: Leveraging the New JSON Native Datatype in Oracle 21cGoing Native: Leveraging the New JSON Native Datatype in Oracle 21c
Going Native: Leveraging the New JSON Native Datatype in Oracle 21cJim Czuprynski
 
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark BrocatoSenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark BrocatoSencha
 
外部環境への依存をテストする
外部環境への依存をテストする外部環境への依存をテストする
外部環境への依存をテストするShunsuke Maeda
 
GraphQL, Redux, and React
GraphQL, Redux, and ReactGraphQL, Redux, and React
GraphQL, Redux, and ReactKeon Kim
 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the ASTJarrod Overson
 
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseCodepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseSages
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
For each task, submit your source java code file.(1) Objective Im.pdf
For each task, submit your source java code file.(1) Objective Im.pdfFor each task, submit your source java code file.(1) Objective Im.pdf
For each task, submit your source java code file.(1) Objective Im.pdfdhavalbl38
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS ProgrammersDavid Rodenas
 
Advance MapReduce Concepts - Module 4
Advance MapReduce Concepts - Module 4Advance MapReduce Concepts - Module 4
Advance MapReduce Concepts - Module 4Rohit Agrawal
 
React new features and intro to Hooks
React new features and intro to HooksReact new features and intro to Hooks
React new features and intro to HooksSoluto
 

Similar to Selectors and normalizing state shape (20)

Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]
 
Data normalization &amp; memoized denormalization
Data normalization &amp; memoized denormalizationData normalization &amp; memoized denormalization
Data normalization &amp; memoized denormalization
 
Using Array Approach, Linked List approach, and Delete Byte Approach.pdf
Using Array Approach, Linked List approach, and Delete Byte Approach.pdfUsing Array Approach, Linked List approach, and Delete Byte Approach.pdf
Using Array Approach, Linked List approach, and Delete Byte Approach.pdf
 
Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3 Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
SE2016 Android Mikle Anokhin "Speed up application development with data bind...
SE2016 Android Mikle Anokhin "Speed up application development with data bind...SE2016 Android Mikle Anokhin "Speed up application development with data bind...
SE2016 Android Mikle Anokhin "Speed up application development with data bind...
 
Controller specs
Controller specsController specs
Controller specs
 
Going Native: Leveraging the New JSON Native Datatype in Oracle 21c
Going Native: Leveraging the New JSON Native Datatype in Oracle 21cGoing Native: Leveraging the New JSON Native Datatype in Oracle 21c
Going Native: Leveraging the New JSON Native Datatype in Oracle 21c
 
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark BrocatoSenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
 
外部環境への依存をテストする
外部環境への依存をテストする外部環境への依存をテストする
外部環境への依存をテストする
 
GraphQL, Redux, and React
GraphQL, Redux, and ReactGraphQL, Redux, and React
GraphQL, Redux, and React
 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
 
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseCodepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
 
Grammarware Memes
Grammarware MemesGrammarware Memes
Grammarware Memes
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
For each task, submit your source java code file.(1) Objective Im.pdf
For each task, submit your source java code file.(1) Objective Im.pdfFor each task, submit your source java code file.(1) Objective Im.pdf
For each task, submit your source java code file.(1) Objective Im.pdf
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
Advance MapReduce Concepts - Module 4
Advance MapReduce Concepts - Module 4Advance MapReduce Concepts - Module 4
Advance MapReduce Concepts - Module 4
 
spring-tutorial
spring-tutorialspring-tutorial
spring-tutorial
 
React new features and intro to Hooks
React new features and intro to HooksReact new features and intro to Hooks
React new features and intro to Hooks
 

Recently uploaded

Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile EnvironmentVictorSzoltysek
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 

Recently uploaded (20)

Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 

Selectors and normalizing state shape

  • 1. SELECTORS and NORMALIZING STATE SHAPE Improving performance in Redux Muntasir Chowdhury
  • 3. const mapStateToProps = state => { return { attributeOne: state.attributeOne, attributeTwo: state.attributeTwo, }; }
  • 4. mapStateToProps() 1. Runs when any part of the Redux store updates 2. Shallow compare of computed values (previous and new) Shallow Compare Render Do nothing Not equal Equal
  • 5. What is a selector?
  • 6. What is a selector? Code that derives data
  • 7. mapStateToProps = state => ( { articles: state.articles }); A simple selector
  • 8. mapStateToProps = state => ( { firstThreeArticles: state.articles.splice(0, 3) }); Transform Data
  • 9. function getFirstThreeArticles(state) { return state.articles.slice(0, 3); } mapStateToProps = state => ( { firstThreeArticles: getFirstThreeArticles(state) }); Extract to function
  • 11. function filterArticles(articles, filter) { switch(filter) { “SHOW_ALL”: return articles; “UNREAD”: return articles.filter(a => a.unread); “READ”: return articles.filter(a => !a.unread); } } mapStateToProps = state => ( { articles: filterArticles(state.articles, state.filter) });
  • 12. function filterArticles(articles, filter) { switch(filter) { “SHOW_ALL”: return articles; “UNREAD”: return articles.filter(a => a.unread); “READ”: return articles.filter(a => !a.unread); } } mapStateToProps = state => ( { articles: filterArticles(state.articles, state.filter), usersOnline: state.usersOnline });
  • 14. function filterArticles(articles, filter) { switch(filter) { “SHOW_ALL”: return articles; “UNREAD”: return articles.filter(a => a.unread); “READ”: return articles.filter(a => !a.unread); } } mapStateToProps = state => ( { articles: filterArticles(state.articles, state.filter), usersOnline: state.usersOnline }); state = { articles: [......], filter: "UNREAD", usersOnline: 1629 }
  • 15. function filterArticles(articles, filter) { switch(filter) { “SHOW_ALL”: return articles; “UNREAD”: return articles.filter(a => a.unread); “READ”: return articles.filter(a => !a.unread); } } mapStateToProps = state => ( { articles: filterArticles(state.articles, state.filter), usersOnline: state.usersOnline }); state = { articles: [......], filter: "UNREAD", usersOnline: 1629 } state = { articles: [......], filter: "UNREAD", usersOnline: 2004 }
  • 20. function filterArticles(articles, filter) { switch(filter) { “SHOW_ALL”: return articles; “UNREAD”: return articles.filter(a => a.unread); “READ”: return articles.filter(a => !a.unread); } } mapStateToProps = state => ( { articles: filterArticles(state.articles, state.filter), usersOnline: state.usersOnline });
  • 21. import { createSelector } from 'reselect' const getFilter = (state) => state.filter; const getArticles = (state) => state.articles; export const filterArticles = createSelector( [ getFilter, getArticles ], (articles, filter) => { switch(filter) { “SHOW_ALL”: return articles; “UNREAD”: return articles.filter(a => a.unread); “READ”: return articles.filter(a => !a.unread); } } )
  • 22. Connect Selector to Redux Store
  • 23. import { connect } from 'react-redux'; import Articles from '../components/TodoList'; import { filterArticles } from '../selectors';   const mapStateToProps = state => { return { articles: filterArticles(state), usersOnline: state.usersOnline } }    const ArticleList = connect(mapStateToProps, null)(Articles)   export default ArticleList
  • 24. NORMALIZING STATE SHAPE Nested State vs Normalized State
  • 26. const articles = [ { id : "artcle1", user : {userId: “ui1”, username : "user1", name : "User 1"}, body : "......", comments : [ { id : "comment1", user : {userId: "ui2", username : "user2", name : "User 2"}, comment : ".....", }, { id : "comment2", user : {userId: "ui3", username : "user3", name : "User 3"}, comment : ".....", } ] }, Nested State
  • 27. { id : "article2", user : {username : "user2", name : "User 2"}, body : "......", comments : [ { id : "comment3", user : {userId: "ui3", username : "user3", name : "User 3"}, comment : ".....", }, { id : "comment4", user : {userId: "ui1", username : "user1", name : "User 1"}, comment : ".....", } ] } …… ]; Nested State
  • 28. //articleListContainer.js mapStateToProps = (state) => ({ articles: state.articles }); // articleList.js const ArticleList = (articles) => ({ articles.map(article => <Article article=article />) }); Selecting Nested State
  • 29. // article.js const Article = (article) => ({ <div>article.content</div> { article.comments.forEach(comments) => <Comment comment=comment /> } }); // comment.js const Comment = (comment) => ({ <div>comment.content</div> <User user=comment.user /> }); Selecting Nested State
  • 30. // user.js const User = (user) => ({ <div>user.name</div> }); Selecting Nested State
  • 33. //action.js function changeUserName(userId, name) { return { type: CHANGE_USER_NAME, payload: { name } }; } Updating Nested State
  • 34. //reducer.js const posts = (state, action) => { switch(action.type) { case "CHANGE_USER_NAME": // find every post // where the user as the author of the post // or as the author of one of its comments } } Updating Nested State
  • 35. 1. Difficult to update a. Duplicate data b. Complex reducer logic due to nesting 2. Higher chance of redundant re-renders Nested State
  • 37. //articles_reducer.js articles : { byId : { "article1" : { id : "article1", user : "user1", body : "......", comments : ["comment1", "comment2"] }, "article2" : { id : "article2", user : "user2", body : "......", comments : ["comment3", "comment4", "comment5"] } }, allIds : ["article1", "article2"] } Normalized State
  • 38. //comments_reducer.js comments : { byId : { "comment1" : { id : "comment1", user : "user2", comment : ".....", }, "comment2" : { id : "comment2", user : "user3", comment : ".....", }, "comment3" : { id : "comment3", user : "user3", comment : ".....", } }, allIds : ["comment1", "comment2", "comment3"] } Normalized State
  • 39. //users_reducer.js users : { byId : { "user1" : { username : "user1", name : "User 1", } "user2" : { username : "user2", name : "User 2", } "user3" : { username : "user3", name : "User 3", } }, allIds : ["user1", "user2", "user3"] } Normalized State
  • 40. //articleListContainer.js mapStateToProps = (state) => ({ articles: state.articles.allIds }); // articleList.js const ArticleList = (articleIds) => ({ articles.map(articleId => <Article articleId=articleId />) }); Selecting Normalized State
  • 41. // article.js const Article = (article) => ({ <div>article.content</div> { article.comments.map(commentIds => <CommentContainer commentId=commentId /> } }); Selecting Normalized State
  • 42. Selecting Normalized State //commentContainer.js mapStateToProps = (state, ownProps) => ({ comment: state.comments.byId[ownProps.commentId] }); // comment.js const Comment = (comment) => ({ <div>comment.content</div> <UserContainer user=comment.user /> });
  • 43. Selecting Normalized State //userContainer.js mapStateToProps = (state, ownProps) => ({ user: state.user.byId[ownProps.userId] }); // user.js const User = (user) => ({ <div>user.name</div> });
  • 45. ArticleList Article Comment User User Comment ….. Article ….. Redux Storeconnect() connect() connect() connect()
  • 46. //action.js function changeUserName(userId, name) { return { type: CHANGE_USER_NAME, payload: { name } }; } Updating Normalized State
  • 47. //userReducer.js const usersById = (state, action) => { switch(action.type) { case "CHANGE_USER_NAME": userId = action.payload.id; changedUser = { ...state[userId], name: action.payload.name }; return { ...state, [userId] : changedUser }; default: return state; } } const usersReducer = combineReducers({ byId: usersById, allIds: [....] }); Updating Normalized State
  • 48. Normalized State 1. Easy to update a. Single copy of data b. Reducer logic more manageable (less nesting) 2. More connected & independent components -> less re-renders
  • 49. Other Topics ● Multiple instances of memoized selectors ● Relationships and Tables (treating Redux like a relational DB) ● Normalizing nested data from API using Normalizr