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 />
</>
);
}
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)
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
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
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>
);
}
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