SlideShare a Scribd company logo
Boris Litvinsky, Tech Lead @ Wix
Road to Async Nirvana
borisl@wix.com twitter@borislit linkedin/borislit github.com/borislit
class ProfilePage extends Component {
constructor () {
this.state = {
error: false,
};
}
componentDidMount () {
fetchUser()
.then(user => {
this.setState({
user,
});
})
.catch(() => this.setState({ error: true }));
}
//...
//...
render() {
if (this.state.error) {
return <p>Error!</p>;
}
if (!this.state.user) {
return <p>Loading profile...</ p>;
}
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
}
class ProfilePage extends Component {
constructor() {
this.state = {
error: false,
};
}
componentDidMount() {
fetchUser()
.then(user => {
this.setState({
user,
});
})
.catch(() => this.setState({ error: true }));
}
//...
//...
render() {
if (this.state.error) {
return <p>Error!</p>;
}
if (!this.state.user) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
}
class ProfilePage extends Component {
constructor() {
this.state = {
error: false,
};
}
componentDidMount() {
fetchUser()
.then( user => {
this.setState({
user,
});
})
.catch(() => this.setState({ error: true }));
}
//...
//...
render() {
if (this.state.error) {
return <p>Error!</p>;
}
if (!this.state.user) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
}
How is this OK???
This is NOT HOW YOU WRITE JAVASCRIPT!
THIS is how You write Javascript!
function ProfilePage() {
console.log('Loading User Profile...' );
try {
const timeline = await ProfileTimeline ();
console.log('Timeline', timeline);
} catch (e) {
console.log('Error', e);
}
}
Hooks for fetching, caching and updating
asynchronous data in React
But First,
Let’s talk Hook
Component
Props
State
UI
React in a Slide
Component
Props
State
UI
React in a Slide
Missing in Functional
Component
function ProfilePage() {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser().then(u => setUser(u));
}, []);
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
▪ useState is a Hook
that lets you add
React state to
function components
function ProfilePage() {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser().then(u => setUser(u));
}, []);
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
▪ useState is a Hook
that lets you add
React state to
function components
▪ useEffect lets you
perform side effects in
function components
function ProfilePage() {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser().then(u => setUser(u));
}, []);
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
▪ useState is a Hook
that lets you add
React state to
function components
▪ useEffect lets you
perform side effects in
function components
function ProfilePage() {
const [user, setUser] = useState(null);
const [error, setError] = useState(false);
useEffect(() => {
fetchUser().then(u => setUser(u)).catch(() => setUser(true));
}, []);
if (error) {
return <p>Error!</p>;
}
if (user === null) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
▪ Compose hooks to
create custom hooks
function useProfile() {
const [user, setUser] = useState(null);
const [error, setError] = useState(false);
useEffect(() => {
fetchUser().then(u => setUser(u)).catch(() => setUser(true));
}, []);
return {user , error};
}
function ProfilePage() {
const {user, error} = useProfile();
if (user === null) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
Components are Functions
Hooks are Functions
Functions can Compose
▪ Compose hooks to
create custom hooks
function useProfile() {
const [user, setUser] = useState(null);
const [error, setError] = useState(false);
useEffect(() => {
fetchUser().then(u => setUser(u)).catch(() => setUser(true));
}, []);
return {user , error};
}
function ProfilePage() {
const {user, error} = useProfile();
if (user === null) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
The Component...
▪ Doesn’t know what’s the source of the data
▪ Does know that it will be notified when the data changes
New Dog, Old Issue
function useProfile() {
const [user, setUser] = useState(null);
const [error, setError] = useState(false);
useEffect(() => {
fetchUser().then(u => setUser(u)).catch(() => setUser(true));
}, []);
return { user, error };
}
function ProfilePage() {
const { user, error } = useProfile();
if (user === null) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
Local to a Component
React
Context
State
Management
Not All State is Born Equal
▪ Server state and component state serve different purposes
▪ Server state is global, while component state is local
▪ Server has unique concerns (caching, pagination, synchronization)
Not All State is Born Equal
Enter
1. Abstracts Away Async
Call
2. Handles requests
states
3. Stores Results in a
cache
function useProfile() {
const [user, setUser] = useState(null);
const [error, setError] = useState(false);
useEffect(() => {
fetchUser().then(u => setUser(u)).catch(() => setUser(true));
}, []);
return { user, error };
}
function ProfilePage() {
const { user, error } = useProfile();
if (user === null) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
function useProfile() {
return useQuery([user, id],(id) => fetchUser(id));
}
function ProfilePage() {
const { user, error } = useProfile();
if (user === null) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{user.name}</h1>
<ProfileTimeline />
</>
);
}
1. Abstracts Away Async
Call
2. Handles requests
states
3. Stores Results in a
cache
React Query Gives You...
▪ Loading states
▪ Mutations
▪ Optimistic updates
▪ Calls de-duping
▪ Pagination
▪ Query Dependencies
▪ Caching
const {
isLoading,
isSuccess,
isError,
data,
error,
failureCount,
refetch,
retry
} = useQuery(/*..*/)
const [mutate] = useMutation(addTodo, {
onSuccess: () => {
queryCache.refetchQueries('todos')
queryCache.refetchQueries('reminders')
},
})
Query/Mutation Dependency
Caching
function ChildComponent() {
const { data } = useQuery('todo');
return <div>{data}</div>;
}
function Root() {
const { data } = useQuery('todo');
//Do Something With Todos
return <ChildComponent />;
}
Resolved from
cache
Fires a request
Self Contained Components
Location-Independent
Caching
function ChildComponent() {
const { data } = useQuery('todo');
return <div>{data}</div>;
}
function Root() {
const { data } = useQuery('todo');
const [shouldRenderChild, setShouldRenderChild] = useState(false);
//Do Something With Todos
return <div>{shouldRenderChild && <ChildComponent />} </div>;
}
Resolved from
cache
Fires a request
This can be Addictive
Caching
function ChildComponent() {
const { data } = useQuery('todo');
return <div>{data}</div>;
}
function Root() {
const { data } = useQuery('todo');
//Do Something With Todos
return <ChildComponent />;
}
ChildComponent tests
become async
Root tests
become async
Leaving You with some Suspense
Where we stand function ProfilePage() {
const { user, isError, isLoading } = useProfile();
if (isError) {
return <p>Error</p>;
}
if (isLoading) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{data.name}</h1>
</>
);
}
Where we stand
▪ Handle missing data
▪ Handling errors
▪ Boilerplate
▪ What if the
component is
reusable?
function ProfilePage() {
const { user, isError, isLoading } = useProfile();
if (isError) {
return <p>Error</p>;
}
if (isLoading) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{data.name}</h1>
</>
);
}
THIS is how You write Javascript!
function ProfilePage() {
console.log('Loading User Profile...' );
try {
const timeline = await ProfileTimeline ();
console.log('Timeline', timeline);
} catch (e) {
console.log('Error', e);
}
}
Where we stand
function ProfilePage() {
const { user, isError, isLoading } = useProfile();
if (isError) {
return <p>Error</p>;
}
if (isLoading) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{data.name}</h1>
</>
);
}
Solved by
Error Boundaries
Where we stand function ProfilePage() {
const { user, isLoading } = useProfile();
if (isLoading) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{data.name}</h1>
</>
);
}
<ErrorBoundery>
<ProfilePage />
</ErrorBoundery>
Error Boundary
Where we stand
function ProfilePage() {
const { user, isLoading } = useProfile();
if (isLoading) {
return <p>Loading profile...</p>;
}
return (
<>
<h1>{data.name}</h1>
</>
);
}
?
<Suspense> component lets you “wait” for any
asynchronous work and declaratively specify a
loading state (like a spinner) while we’re waiting
The Suspense Way
▪ Try to render ProfileDetails
▪ ProfileDetails tries reading
user details
▪ React “suspends”
ProfileDetails rendering and
renders fallback
▪ React “resumes”
ProfileDetails rendering once
user details are available
function ProfilePage() {
return (
<Suspense fallback={<h1>Loading profile...</h1>}>
<ProfileDetails />
</Suspense>
);
}
function ProfileDetails() {
// Try to read user info, although it might not have loaded yet
const user = useProfile();
return <h1>{user.name}</h1>;
}
The Suspense Way
▪ Suspense is a
component
▪ “Suspended”
components will fallback
to the closest Suspense
ancestor
function ProfilePage() {
return (
<Suspense fallback={<h1>Loading profile...</h1>}>
<ProfileDetails />
<Suspense fallback={<h1>Loading posts...</h1>}>
<ProfileTimeline />
</Suspense>
</Suspense>
);
}
function ProfileDetails() {
const user = useProfile();
return <h1>{user.name}</h1>;
}
This is HARD*
function Root() {
const { data } = useQuery('todo');
return <ChildComponent />;
}
React-Query supports Suspense OOB
Suspends
Rendering
This get EVERYBODY...
▪ Thinking about resilience
▪ Thinking about performance
At Wix this is now an integral part of product
design and architecture review
Summary
Summary
▪ Hooks are a paradigm shift
▪ React Query uses hooks to simplify fetching/mutating async data
▪ React Query classifying your state.
▪ Cache responses allows co locating the data requirements with the
components
▪ Combined with Suspense, it promotes error handling, resilience and
performances
Thank You
borisl@wix.com twitter@borislit linkedin/borislit github.com/borislit

More Related Content

What's hot

The Rails Way
The Rails WayThe Rails Way
The Rails Way
Michał Orman
 
Beyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsBeyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS Apps
Rebecca Murphey
 
Functionality Focused Code Organization
Functionality Focused Code OrganizationFunctionality Focused Code Organization
Functionality Focused Code Organization
Rebecca Murphey
 
Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5
성일 한
 
BVJS
BVJSBVJS
Building evented single page applications
Building evented single page applicationsBuilding evented single page applications
Building evented single page applications
Steve Smith
 
jQuery: out with the old, in with the new
jQuery: out with the old, in with the newjQuery: out with the old, in with the new
jQuery: out with the old, in with the new
Remy Sharp
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
sergioafp
 
YUI on the go
YUI on the goYUI on the go
YUI on the go
Christian Heilmann
 
Jquery Fundamentals
Jquery FundamentalsJquery Fundamentals
Jquery Fundamentals
Rebecca Murphey
 
JQuery In Rails
JQuery In RailsJQuery In Rails
JQuery In Rails
Louie Zhao
 
Symfony2. Form and Validation
Symfony2. Form and ValidationSymfony2. Form and Validation
Symfony2. Form and Validation
Vladimir Doroshenko
 
Acceptance Testing with Webrat
Acceptance Testing with WebratAcceptance Testing with Webrat
Acceptance Testing with Webrat
Luismi Cavallé
 
Growing jQuery
Growing jQueryGrowing jQuery
Growing jQuery
gueste8d8bc
 
BEAR DI
BEAR DIBEAR DI
jQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a TreejQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a Tree
adamlogic
 
Tinkerbelles return home from their Guinness world-record attempt on Sunday
Tinkerbelles return home from their Guinness world-record attempt on SundayTinkerbelles return home from their Guinness world-record attempt on Sunday
Tinkerbelles return home from their Guinness world-record attempt on Sunday
chicagonewsyesterday
 
Dundee University HackU 2013 - Mojito
Dundee University HackU 2013 - MojitoDundee University HackU 2013 - Mojito
Dundee University HackU 2013 - Mojito
smartads
 
Backbone - TDC 2011 Floripa
Backbone - TDC 2011 FloripaBackbone - TDC 2011 Floripa
Backbone - TDC 2011 Floripa
Rafael Felix da Silva
 
FRP and Bacon.js
FRP and Bacon.jsFRP and Bacon.js
FRP and Bacon.js
Starbuildr
 

What's hot (20)

The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
Beyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsBeyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS Apps
 
Functionality Focused Code Organization
Functionality Focused Code OrganizationFunctionality Focused Code Organization
Functionality Focused Code Organization
 
Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5
 
BVJS
BVJSBVJS
BVJS
 
Building evented single page applications
Building evented single page applicationsBuilding evented single page applications
Building evented single page applications
 
jQuery: out with the old, in with the new
jQuery: out with the old, in with the newjQuery: out with the old, in with the new
jQuery: out with the old, in with the new
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
YUI on the go
YUI on the goYUI on the go
YUI on the go
 
Jquery Fundamentals
Jquery FundamentalsJquery Fundamentals
Jquery Fundamentals
 
JQuery In Rails
JQuery In RailsJQuery In Rails
JQuery In Rails
 
Symfony2. Form and Validation
Symfony2. Form and ValidationSymfony2. Form and Validation
Symfony2. Form and Validation
 
Acceptance Testing with Webrat
Acceptance Testing with WebratAcceptance Testing with Webrat
Acceptance Testing with Webrat
 
Growing jQuery
Growing jQueryGrowing jQuery
Growing jQuery
 
BEAR DI
BEAR DIBEAR DI
BEAR DI
 
jQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a TreejQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a Tree
 
Tinkerbelles return home from their Guinness world-record attempt on Sunday
Tinkerbelles return home from their Guinness world-record attempt on SundayTinkerbelles return home from their Guinness world-record attempt on Sunday
Tinkerbelles return home from their Guinness world-record attempt on Sunday
 
Dundee University HackU 2013 - Mojito
Dundee University HackU 2013 - MojitoDundee University HackU 2013 - Mojito
Dundee University HackU 2013 - Mojito
 
Backbone - TDC 2011 Floripa
Backbone - TDC 2011 FloripaBackbone - TDC 2011 Floripa
Backbone - TDC 2011 Floripa
 
FRP and Bacon.js
FRP and Bacon.jsFRP and Bacon.js
FRP and Bacon.js
 

Similar to Road to Async Nirvana

jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journey
Huiyi Yan
 
Building Evented Single Page Applications
Building Evented Single Page ApplicationsBuilding Evented Single Page Applications
Building Evented Single Page Applications
Steve Smith
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
Boris Dinkevich
 
HTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - AltranHTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - Altran
Robert Nyman
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
Christoffer Noring
 
Creating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdfCreating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdf
ShaiAlmog1
 
Django
DjangoDjango
Django
webuploader
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in Swift
Peter Friese
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
Joseph Chiang
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
rajivmordani
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
Ryunosuke SATO
 
JSP
JSPJSP
JavaScript patterns
JavaScript patternsJavaScript patterns
JavaScript patterns
Norihito YAMAKAWA
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
偉格 高
 
Express JS
Express JSExpress JS
Express JS
Alok Guha
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
Michael Girouard
 
JSGeneve - Backbone.js
JSGeneve - Backbone.jsJSGeneve - Backbone.js
JSGeneve - Backbone.js
Pierre Spring
 
Week 12 code
Week 12 codeWeek 12 code
Week 12 code
abhi7692271
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScript
Ryan Anklam
 
Taming forms with React
Taming forms with ReactTaming forms with React
Taming forms with React
GreeceJS
 

Similar to Road to Async Nirvana (20)

jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journey
 
Building Evented Single Page Applications
Building Evented Single Page ApplicationsBuilding Evented Single Page Applications
Building Evented Single Page Applications
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
HTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - AltranHTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - Altran
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
 
Creating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdfCreating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdf
 
Django
DjangoDjango
Django
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in Swift
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
JSP
JSPJSP
JSP
 
JavaScript patterns
JavaScript patternsJavaScript patterns
JavaScript patterns
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
Express JS
Express JSExpress JS
Express JS
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
 
JSGeneve - Backbone.js
JSGeneve - Backbone.jsJSGeneve - Backbone.js
JSGeneve - Backbone.js
 
Week 12 code
Week 12 codeWeek 12 code
Week 12 code
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScript
 
Taming forms with React
Taming forms with ReactTaming forms with React
Taming forms with React
 

More from Boris Litvinsky

ReactiveConf - Not all indecision are bad
ReactiveConf - Not all indecision are badReactiveConf - Not all indecision are bad
ReactiveConf - Not all indecision are bad
Boris Litvinsky
 
Your IDE Deserves Better
Your IDE Deserves BetterYour IDE Deserves Better
Your IDE Deserves Better
Boris Litvinsky
 
The ultimate guide for Software Procrastination
The ultimate guide for Software ProcrastinationThe ultimate guide for Software Procrastination
The ultimate guide for Software Procrastination
Boris Litvinsky
 
CDD @ FED
CDD @ FEDCDD @ FED
CDD @ FED
Boris Litvinsky
 
Test Driven Culture
Test Driven CultureTest Driven Culture
Test Driven Culture
Boris Litvinsky
 
How to build 100m websites
How to build 100m websitesHow to build 100m websites
How to build 100m websites
Boris Litvinsky
 
Name in Vain: Improving design one word at a time
Name in Vain: Improving design one word at a timeName in Vain: Improving design one word at a time
Name in Vain: Improving design one word at a time
Boris Litvinsky
 

More from Boris Litvinsky (7)

ReactiveConf - Not all indecision are bad
ReactiveConf - Not all indecision are badReactiveConf - Not all indecision are bad
ReactiveConf - Not all indecision are bad
 
Your IDE Deserves Better
Your IDE Deserves BetterYour IDE Deserves Better
Your IDE Deserves Better
 
The ultimate guide for Software Procrastination
The ultimate guide for Software ProcrastinationThe ultimate guide for Software Procrastination
The ultimate guide for Software Procrastination
 
CDD @ FED
CDD @ FEDCDD @ FED
CDD @ FED
 
Test Driven Culture
Test Driven CultureTest Driven Culture
Test Driven Culture
 
How to build 100m websites
How to build 100m websitesHow to build 100m websites
How to build 100m websites
 
Name in Vain: Improving design one word at a time
Name in Vain: Improving design one word at a timeName in Vain: Improving design one word at a time
Name in Vain: Improving design one word at a time
 

Recently uploaded

Understanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine LearningUnderstanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine Learning
SUTEJAS
 
Engineering Drawings Lecture Detail Drawings 2014.pdf
Engineering Drawings Lecture Detail Drawings 2014.pdfEngineering Drawings Lecture Detail Drawings 2014.pdf
Engineering Drawings Lecture Detail Drawings 2014.pdf
abbyasa1014
 
NATURAL DEEP EUTECTIC SOLVENTS AS ANTI-FREEZING AGENT
NATURAL DEEP EUTECTIC SOLVENTS AS ANTI-FREEZING AGENTNATURAL DEEP EUTECTIC SOLVENTS AS ANTI-FREEZING AGENT
NATURAL DEEP EUTECTIC SOLVENTS AS ANTI-FREEZING AGENT
Addu25809
 
Hematology Analyzer Machine - Complete Blood Count
Hematology Analyzer Machine - Complete Blood CountHematology Analyzer Machine - Complete Blood Count
Hematology Analyzer Machine - Complete Blood Count
shahdabdulbaset
 
Material for memory and display system h
Material for memory and display system hMaterial for memory and display system h
Material for memory and display system h
gowrishankartb2005
 
Certificates - Mahmoud Mohamed Moursi Ahmed
Certificates - Mahmoud Mohamed Moursi AhmedCertificates - Mahmoud Mohamed Moursi Ahmed
Certificates - Mahmoud Mohamed Moursi Ahmed
Mahmoud Morsy
 
gray level transformation unit 3(image processing))
gray level transformation unit 3(image processing))gray level transformation unit 3(image processing))
gray level transformation unit 3(image processing))
shivani5543
 
Casting-Defect-inSlab continuous casting.pdf
Casting-Defect-inSlab continuous casting.pdfCasting-Defect-inSlab continuous casting.pdf
Casting-Defect-inSlab continuous casting.pdf
zubairahmad848137
 
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
insn4465
 
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECTCHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
jpsjournal1
 
CompEx~Manual~1210 (2).pdf COMPEX GAS AND VAPOURS
CompEx~Manual~1210 (2).pdf COMPEX GAS AND VAPOURSCompEx~Manual~1210 (2).pdf COMPEX GAS AND VAPOURS
CompEx~Manual~1210 (2).pdf COMPEX GAS AND VAPOURS
RamonNovais6
 
BRAIN TUMOR DETECTION for seminar ppt.pdf
BRAIN TUMOR DETECTION for seminar ppt.pdfBRAIN TUMOR DETECTION for seminar ppt.pdf
BRAIN TUMOR DETECTION for seminar ppt.pdf
LAXMAREDDY22
 
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
IJECEIAES
 
Advanced control scheme of doubly fed induction generator for wind turbine us...
Advanced control scheme of doubly fed induction generator for wind turbine us...Advanced control scheme of doubly fed induction generator for wind turbine us...
Advanced control scheme of doubly fed induction generator for wind turbine us...
IJECEIAES
 
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdfBPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
MIGUELANGEL966976
 
Literature Review Basics and Understanding Reference Management.pptx
Literature Review Basics and Understanding Reference Management.pptxLiterature Review Basics and Understanding Reference Management.pptx
Literature Review Basics and Understanding Reference Management.pptx
Dr Ramhari Poudyal
 
Generative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of contentGenerative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of content
Hitesh Mohapatra
 
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student MemberIEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
VICTOR MAESTRE RAMIREZ
 
Engine Lubrication performance System.pdf
Engine Lubrication performance System.pdfEngine Lubrication performance System.pdf
Engine Lubrication performance System.pdf
mamamaam477
 
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
Yasser Mahgoub
 

Recently uploaded (20)

Understanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine LearningUnderstanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine Learning
 
Engineering Drawings Lecture Detail Drawings 2014.pdf
Engineering Drawings Lecture Detail Drawings 2014.pdfEngineering Drawings Lecture Detail Drawings 2014.pdf
Engineering Drawings Lecture Detail Drawings 2014.pdf
 
NATURAL DEEP EUTECTIC SOLVENTS AS ANTI-FREEZING AGENT
NATURAL DEEP EUTECTIC SOLVENTS AS ANTI-FREEZING AGENTNATURAL DEEP EUTECTIC SOLVENTS AS ANTI-FREEZING AGENT
NATURAL DEEP EUTECTIC SOLVENTS AS ANTI-FREEZING AGENT
 
Hematology Analyzer Machine - Complete Blood Count
Hematology Analyzer Machine - Complete Blood CountHematology Analyzer Machine - Complete Blood Count
Hematology Analyzer Machine - Complete Blood Count
 
Material for memory and display system h
Material for memory and display system hMaterial for memory and display system h
Material for memory and display system h
 
Certificates - Mahmoud Mohamed Moursi Ahmed
Certificates - Mahmoud Mohamed Moursi AhmedCertificates - Mahmoud Mohamed Moursi Ahmed
Certificates - Mahmoud Mohamed Moursi Ahmed
 
gray level transformation unit 3(image processing))
gray level transformation unit 3(image processing))gray level transformation unit 3(image processing))
gray level transformation unit 3(image processing))
 
Casting-Defect-inSlab continuous casting.pdf
Casting-Defect-inSlab continuous casting.pdfCasting-Defect-inSlab continuous casting.pdf
Casting-Defect-inSlab continuous casting.pdf
 
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
 
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECTCHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
 
CompEx~Manual~1210 (2).pdf COMPEX GAS AND VAPOURS
CompEx~Manual~1210 (2).pdf COMPEX GAS AND VAPOURSCompEx~Manual~1210 (2).pdf COMPEX GAS AND VAPOURS
CompEx~Manual~1210 (2).pdf COMPEX GAS AND VAPOURS
 
BRAIN TUMOR DETECTION for seminar ppt.pdf
BRAIN TUMOR DETECTION for seminar ppt.pdfBRAIN TUMOR DETECTION for seminar ppt.pdf
BRAIN TUMOR DETECTION for seminar ppt.pdf
 
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
 
Advanced control scheme of doubly fed induction generator for wind turbine us...
Advanced control scheme of doubly fed induction generator for wind turbine us...Advanced control scheme of doubly fed induction generator for wind turbine us...
Advanced control scheme of doubly fed induction generator for wind turbine us...
 
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdfBPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
 
Literature Review Basics and Understanding Reference Management.pptx
Literature Review Basics and Understanding Reference Management.pptxLiterature Review Basics and Understanding Reference Management.pptx
Literature Review Basics and Understanding Reference Management.pptx
 
Generative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of contentGenerative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of content
 
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student MemberIEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
 
Engine Lubrication performance System.pdf
Engine Lubrication performance System.pdfEngine Lubrication performance System.pdf
Engine Lubrication performance System.pdf
 
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
 

Road to Async Nirvana

  • 1. Boris Litvinsky, Tech Lead @ Wix Road to Async Nirvana borisl@wix.com twitter@borislit linkedin/borislit github.com/borislit
  • 2. class ProfilePage extends Component { constructor () { this.state = { error: false, }; } componentDidMount () { fetchUser() .then(user => { this.setState({ user, }); }) .catch(() => this.setState({ error: true })); } //... //... render() { if (this.state.error) { return <p>Error!</p>; } if (!this.state.user) { return <p>Loading profile...</ p>; } return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); } }
  • 3. class ProfilePage extends Component { constructor() { this.state = { error: false, }; } componentDidMount() { fetchUser() .then(user => { this.setState({ user, }); }) .catch(() => this.setState({ error: true })); } //... //... render() { if (this.state.error) { return <p>Error!</p>; } if (!this.state.user) { return <p>Loading profile...</p>; } return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); } }
  • 4. class ProfilePage extends Component { constructor() { this.state = { error: false, }; } componentDidMount() { fetchUser() .then( user => { this.setState({ user, }); }) .catch(() => this.setState({ error: true })); } //... //... render() { if (this.state.error) { return <p>Error!</p>; } if (!this.state.user) { return <p>Loading profile...</p>; } return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); } }
  • 5. How is this OK??? This is NOT HOW YOU WRITE JAVASCRIPT!
  • 6. THIS is how You write Javascript! function ProfilePage() { console.log('Loading User Profile...' ); try { const timeline = await ProfileTimeline (); console.log('Timeline', timeline); } catch (e) { console.log('Error', e); } }
  • 7. Hooks for fetching, caching and updating asynchronous data in React
  • 10. Component Props State UI React in a Slide Missing in Functional Component
  • 11. function ProfilePage() { const [user, setUser] = useState(null); useEffect(() => { fetchUser().then(u => setUser(u)); }, []); return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); }
  • 12. ▪ useState is a Hook that lets you add React state to function components function ProfilePage() { const [user, setUser] = useState(null); useEffect(() => { fetchUser().then(u => setUser(u)); }, []); return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); }
  • 13. ▪ useState is a Hook that lets you add React state to function components ▪ useEffect lets you perform side effects in function components function ProfilePage() { const [user, setUser] = useState(null); useEffect(() => { fetchUser().then(u => setUser(u)); }, []); return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); }
  • 14. ▪ useState is a Hook that lets you add React state to function components ▪ useEffect lets you perform side effects in function components function ProfilePage() { const [user, setUser] = useState(null); const [error, setError] = useState(false); useEffect(() => { fetchUser().then(u => setUser(u)).catch(() => setUser(true)); }, []); if (error) { return <p>Error!</p>; } if (user === null) { return <p>Loading profile...</p>; } return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); }
  • 15. ▪ Compose hooks to create custom hooks function useProfile() { const [user, setUser] = useState(null); const [error, setError] = useState(false); useEffect(() => { fetchUser().then(u => setUser(u)).catch(() => setUser(true)); }, []); return {user , error}; } function ProfilePage() { const {user, error} = useProfile(); if (user === null) { return <p>Loading profile...</p>; } return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); }
  • 16. Components are Functions Hooks are Functions Functions can Compose
  • 17. ▪ Compose hooks to create custom hooks function useProfile() { const [user, setUser] = useState(null); const [error, setError] = useState(false); useEffect(() => { fetchUser().then(u => setUser(u)).catch(() => setUser(true)); }, []); return {user , error}; } function ProfilePage() { const {user, error} = useProfile(); if (user === null) { return <p>Loading profile...</p>; } return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); }
  • 18.
  • 19. The Component... ▪ Doesn’t know what’s the source of the data ▪ Does know that it will be notified when the data changes
  • 20. New Dog, Old Issue
  • 21. function useProfile() { const [user, setUser] = useState(null); const [error, setError] = useState(false); useEffect(() => { fetchUser().then(u => setUser(u)).catch(() => setUser(true)); }, []); return { user, error }; } function ProfilePage() { const { user, error } = useProfile(); if (user === null) { return <p>Loading profile...</p>; } return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); } Local to a Component
  • 23. Not All State is Born Equal ▪ Server state and component state serve different purposes ▪ Server state is global, while component state is local ▪ Server has unique concerns (caching, pagination, synchronization)
  • 24. Not All State is Born Equal
  • 25. Enter
  • 26. 1. Abstracts Away Async Call 2. Handles requests states 3. Stores Results in a cache function useProfile() { const [user, setUser] = useState(null); const [error, setError] = useState(false); useEffect(() => { fetchUser().then(u => setUser(u)).catch(() => setUser(true)); }, []); return { user, error }; } function ProfilePage() { const { user, error } = useProfile(); if (user === null) { return <p>Loading profile...</p>; } return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); }
  • 27. function useProfile() { return useQuery([user, id],(id) => fetchUser(id)); } function ProfilePage() { const { user, error } = useProfile(); if (user === null) { return <p>Loading profile...</p>; } return ( <> <h1>{user.name}</h1> <ProfileTimeline /> </> ); } 1. Abstracts Away Async Call 2. Handles requests states 3. Stores Results in a cache
  • 28. React Query Gives You... ▪ Loading states ▪ Mutations ▪ Optimistic updates ▪ Calls de-duping ▪ Pagination ▪ Query Dependencies ▪ Caching const { isLoading, isSuccess, isError, data, error, failureCount, refetch, retry } = useQuery(/*..*/)
  • 29. const [mutate] = useMutation(addTodo, { onSuccess: () => { queryCache.refetchQueries('todos') queryCache.refetchQueries('reminders') }, }) Query/Mutation Dependency
  • 30. Caching function ChildComponent() { const { data } = useQuery('todo'); return <div>{data}</div>; } function Root() { const { data } = useQuery('todo'); //Do Something With Todos return <ChildComponent />; } Resolved from cache Fires a request
  • 31.
  • 33. Caching function ChildComponent() { const { data } = useQuery('todo'); return <div>{data}</div>; } function Root() { const { data } = useQuery('todo'); const [shouldRenderChild, setShouldRenderChild] = useState(false); //Do Something With Todos return <div>{shouldRenderChild && <ChildComponent />} </div>; } Resolved from cache Fires a request
  • 34. This can be Addictive
  • 35. Caching function ChildComponent() { const { data } = useQuery('todo'); return <div>{data}</div>; } function Root() { const { data } = useQuery('todo'); //Do Something With Todos return <ChildComponent />; } ChildComponent tests become async Root tests become async
  • 36. Leaving You with some Suspense
  • 37. Where we stand function ProfilePage() { const { user, isError, isLoading } = useProfile(); if (isError) { return <p>Error</p>; } if (isLoading) { return <p>Loading profile...</p>; } return ( <> <h1>{data.name}</h1> </> ); }
  • 38. Where we stand ▪ Handle missing data ▪ Handling errors ▪ Boilerplate ▪ What if the component is reusable? function ProfilePage() { const { user, isError, isLoading } = useProfile(); if (isError) { return <p>Error</p>; } if (isLoading) { return <p>Loading profile...</p>; } return ( <> <h1>{data.name}</h1> </> ); }
  • 39. THIS is how You write Javascript! function ProfilePage() { console.log('Loading User Profile...' ); try { const timeline = await ProfileTimeline (); console.log('Timeline', timeline); } catch (e) { console.log('Error', e); } }
  • 40. Where we stand function ProfilePage() { const { user, isError, isLoading } = useProfile(); if (isError) { return <p>Error</p>; } if (isLoading) { return <p>Loading profile...</p>; } return ( <> <h1>{data.name}</h1> </> ); } Solved by Error Boundaries
  • 41. Where we stand function ProfilePage() { const { user, isLoading } = useProfile(); if (isLoading) { return <p>Loading profile...</p>; } return ( <> <h1>{data.name}</h1> </> ); } <ErrorBoundery> <ProfilePage /> </ErrorBoundery> Error Boundary
  • 42. Where we stand function ProfilePage() { const { user, isLoading } = useProfile(); if (isLoading) { return <p>Loading profile...</p>; } return ( <> <h1>{data.name}</h1> </> ); } ?
  • 43. <Suspense> component lets you “wait” for any asynchronous work and declaratively specify a loading state (like a spinner) while we’re waiting
  • 44. The Suspense Way ▪ Try to render ProfileDetails ▪ ProfileDetails tries reading user details ▪ React “suspends” ProfileDetails rendering and renders fallback ▪ React “resumes” ProfileDetails rendering once user details are available function ProfilePage() { return ( <Suspense fallback={<h1>Loading profile...</h1>}> <ProfileDetails /> </Suspense> ); } function ProfileDetails() { // Try to read user info, although it might not have loaded yet const user = useProfile(); return <h1>{user.name}</h1>; }
  • 45. The Suspense Way ▪ Suspense is a component ▪ “Suspended” components will fallback to the closest Suspense ancestor function ProfilePage() { return ( <Suspense fallback={<h1>Loading profile...</h1>}> <ProfileDetails /> <Suspense fallback={<h1>Loading posts...</h1>}> <ProfileTimeline /> </Suspense> </Suspense> ); }
  • 46. function ProfileDetails() { const user = useProfile(); return <h1>{user.name}</h1>; } This is HARD*
  • 47. function Root() { const { data } = useQuery('todo'); return <ChildComponent />; } React-Query supports Suspense OOB Suspends Rendering
  • 48. This get EVERYBODY... ▪ Thinking about resilience ▪ Thinking about performance
  • 49. At Wix this is now an integral part of product design and architecture review
  • 51. Summary ▪ Hooks are a paradigm shift ▪ React Query uses hooks to simplify fetching/mutating async data ▪ React Query classifying your state. ▪ Cache responses allows co locating the data requirements with the components ▪ Combined with Suspense, it promotes error handling, resilience and performances
  • 52. Thank You borisl@wix.com twitter@borislit linkedin/borislit github.com/borislit