Skip to content

Instantly share code, notes, and snippets.

@teimurjan
Last active August 3, 2021 08:11
Show Gist options
  • Save teimurjan/7e983afce85e325e84c528f61811c674 to your computer and use it in GitHub Desktop.
Save teimurjan/7e983afce85e325e84c528f61811c674 to your computer and use it in GitHub Desktop.
import { Suspense, useState, useEffect } from 'react';
function toResource(promise) {
let status = "pending";
let result;
let suspender = promise.then(
(r) => {
status = "success";
result = r;
},
(e) => {
status = "error";
result = e;
}
);
return {
read() {
if (status === "pending") {
throw suspender;
} else if (status === "error") {
throw result;
} else if (status === "success") {
return result;
}
}
};
}
const SuspensefulUserProfile = ({ userId }) => {
const [resource, setResource] = useState(toResource(fetchUserProfile(userId)))
useEffect(() => {
setResource(toResource(fetchUserProfile(userId)))
}, [userId)
return (
// PROBLEM #2: The errors should be handled
<ErrorBoundary fallback={<h2>Could not fetch user #{userId}</h2>}>
// PROBLEM #1: Fallback is required to render in loading stage
<Suspense fallback={<p>Loading...</p>}>
<UserProfile resource={resource} />
</Suspense>
</ErrorBoundary>
);
};
const UserProfile = ({ resource }) => {
// PROBLEM #3: Using resource not to wait for the response to come back before we start rendering
const profile = resource.read()
return (
<>
<h1>{data.name}</h1>
<h2>{data.email}</h2>
</>
);
};
const UserProfileList = () => (
<>
<SuspensefulUserProfile userId={1} />
<SuspensefulUserProfile userId={2} />
<SuspensefulUserProfile userId={3} />
</>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment