Skip to content

Instantly share code, notes, and snippets.

@Darmody
Created May 30, 2021 01:59
Show Gist options
  • Save Darmody/c91d84e2d92b4adede48275636d31105 to your computer and use it in GitHub Desktop.
Save Darmody/c91d84e2d92b4adede48275636d31105 to your computer and use it in GitHub Desktop.
/**
* 1) fetch data inside useEffect violate "Render-as-You-Fetch", we should start fetching early.
* 2) fetchUserProfile do not implement as Suspense required, it should work like relay.
* 3) Suspense do not have a fallback, it violate the concurrent UI Patterns.
*/
import React, { Suspense } from "react";
import ReactDOM from "react-dom";
function fetchUserProfile(userId) {
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve({
name: "user" + userId,
email: "user" + userId + "@email.com"
});
}, 2000);
});
return wrapPromise(promise);
}
function wrapPromise(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 data = fetchUserProfile(userId);
return (
<Suspense fallback={<h1>loading...</h1>}>
<UserProfile data={data} />
</Suspense>
);
};
const UserProfile = ({ data }) => {
const user = data.read();
return (
<>
<h1>{user.name}</h1>
<h2>{user.email}</h2>
</>
);
};
const UserProfileList = () => (
<>
<SuspensefulUserProfile userId={1} />
<SuspensefulUserProfile userId={2} />
<SuspensefulUserProfile userId={3} />
</>
);
const rootElement = document.getElementById("root");
ReactDOM.createRoot(rootElement).render(<UserProfileList />);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment