SlideShare a Scribd company logo
1 of 52
Download to read offline
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

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 AppsRebecca Murphey
 
Functionality Focused Code Organization
Functionality Focused Code OrganizationFunctionality Focused Code Organization
Functionality Focused Code OrganizationRebecca Murphey
 
Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5성일 한
 
Building evented single page applications
Building evented single page applicationsBuilding evented single page applications
Building evented single page applicationsSteve 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 newRemy Sharp
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuerysergioafp
 
JQuery In Rails
JQuery In RailsJQuery In Rails
JQuery In RailsLouie Zhao
 
Acceptance Testing with Webrat
Acceptance Testing with WebratAcceptance Testing with Webrat
Acceptance Testing with WebratLuismi Cavallé
 
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 Treeadamlogic
 
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 Sundaychicagonewsyesterday
 
Dundee University HackU 2013 - Mojito
Dundee University HackU 2013 - MojitoDundee University HackU 2013 - Mojito
Dundee University HackU 2013 - Mojitosmartads
 
FRP and Bacon.js
FRP and Bacon.jsFRP and Bacon.js
FRP and Bacon.jsStarbuildr
 

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 journeyHuiyi Yan
 
Building Evented Single Page Applications
Building Evented Single Page ApplicationsBuilding Evented Single Page Applications
Building Evented Single Page ApplicationsSteve Smith
 
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! - AltranRobert Nyman
 
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.pdfShaiAlmog1
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in SwiftPeter Friese
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5arajivmordani
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs偉格 高
 
JSGeneve - Backbone.js
JSGeneve - Backbone.jsJSGeneve - Backbone.js
JSGeneve - Backbone.jsPierre Spring
 
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 JavaScriptRyan Anklam
 
Taming forms with React
Taming forms with ReactTaming forms with React
Taming forms with ReactGreeceJS
 

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 badBoris Litvinsky
 
Your IDE Deserves Better
Your IDE Deserves BetterYour IDE Deserves Better
Your IDE Deserves BetterBoris Litvinsky
 
The ultimate guide for Software Procrastination
The ultimate guide for Software ProcrastinationThe ultimate guide for Software Procrastination
The ultimate guide for Software ProcrastinationBoris Litvinsky
 
How to build 100m websites
How to build 100m websitesHow to build 100m websites
How to build 100m websitesBoris 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 timeBoris 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

Thermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VThermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VDineshKumar4165
 
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELL
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELLPVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELL
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELLManishPatel169454
 
Call Girls Walvekar Nagar Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Walvekar Nagar Call Me 7737669865 Budget Friendly No Advance BookingCall Girls Walvekar Nagar Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Walvekar Nagar Call Me 7737669865 Budget Friendly No Advance Bookingroncy bisnoi
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Call Girls in Nagpur High Profile
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...Call Girls in Nagpur High Profile
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...roncy bisnoi
 
notes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.pptnotes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.pptMsecMca
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756dollysharma2066
 
Double Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueDouble Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueBhangaleSonal
 
Unit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfUnit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfRagavanV2
 
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptxBSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptxfenichawla
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfJiananWang21
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)simmis5
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordAsst.prof M.Gokilavani
 
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Christo Ananth
 
Thermal Engineering Unit - I & II . ppt
Thermal Engineering  Unit - I & II . pptThermal Engineering  Unit - I & II . ppt
Thermal Engineering Unit - I & II . pptDineshKumar4165
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlysanyuktamishra911
 

Recently uploaded (20)

Thermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VThermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - V
 
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELL
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELLPVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELL
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELL
 
Call Girls Walvekar Nagar Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Walvekar Nagar Call Me 7737669865 Budget Friendly No Advance BookingCall Girls Walvekar Nagar Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Walvekar Nagar Call Me 7737669865 Budget Friendly No Advance Booking
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
notes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.pptnotes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.ppt
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
 
Double Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueDouble Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torque
 
Unit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfUnit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdf
 
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptxBSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)
 
NFPA 5000 2024 standard .
NFPA 5000 2024 standard                                  .NFPA 5000 2024 standard                                  .
NFPA 5000 2024 standard .
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
 
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
 
Thermal Engineering Unit - I & II . ppt
Thermal Engineering  Unit - I & II . pptThermal Engineering  Unit - I & II . ppt
Thermal Engineering Unit - I & II . ppt
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghly
 
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
 
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
 

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