I have a bunch of async actions I need to do before a react component can be rendered, and I would like to use React.Suspense
for this. I found an example online:
https://dev.to/smitterhane/swap-out-useeffect-with-suspense-for-data-fetching-in-react-2leb
import React from "react";
import Post from "./Post";
// Variables we will use to replay state of fetch() promise to React
let status = "pending";
let result;
// Start fetching posts even before rendering begins
const userId = JSON.parse(localStorage.getItem("authenticatedUser"))?.id;
const postsData = fetchPosts(userId);
// Posts component (definition)
const Posts = () => {
// No need for loading states
const posts = postsData();
return (
<div style={{ display: "flex", flexWrap: "wrap", gap: "10px" }}>
{posts.map((post, idx) => (
<Post post={post} key={idx} />
))}
</div>
);
};
// Fetch external data
function fetchPosts(userId) {
let url = `https://jsonplaceholder.typicode.com/posts${
userId ? "?userId=" + userId : ""
}`;
let fetching = fetch(url)
.then((res) => res.json())
// Fetch request has gone well
.then((success) => {
status = "fulfilled";
result = success;
})
// Fetch request has failed
.catch((error) => {
status = "rejected";
result = error;
});
return () => {
if (status === "pending") {
throw fetching; // Suspend(A way to tell React data is still fetching)
} else if (status === "rejected") {
throw result; // Result is an error
} else if (status === "fulfilled") {
return result; // Result is a fulfilled promise
}
};
}
export default Posts;
But what if, in this example, userId
would be a prop of Posts - rather than taken from localstorage?
const Posts = ({ userId } ) => {
This seems to be a problem because const postsData = fetchPosts(userId);
is declared outside of the Posts component...
Like the user from this post:
Trying to implement React Suspense boundary and refetching data from API after some events
I ditched all these half-functiong tutorials online, and used the useSWR hook instead.