Last active
September 1, 2021 00:25
-
-
Save nevermind89x/eb9df19b4f1f02c15a0d16bce303fc60 to your computer and use it in GitHub Desktop.
Contra Suspense Code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Working sample can be found on this link: https://codesandbox.io/s/jovial-haze-4q9fk | |
* | |
* Errors found: | |
* 1. First error on SuspensefulUserProfile component was the way the data is being fetched. | |
* This is a Fetch-on-Render approach, instead of fetching and rendering at the same time (Updated to use that one) | |
* | |
* 2. fallback prop must be set as prop on Suspense | |
* 3. I would add and ErrorBoundary so in case it fails thats handled | |
* 4. This is not an error but we could also add SuspenseList to handle the display order (still only on experiment version I think) | |
*/ | |
// Will add a comment above each Component when it lives on a separate file, but please refer to the codesandbox | |
// with the full example | |
import { Suspense, FC } from 'react'; | |
// use-asunc-resource, using this library to create the resource, | |
// but can be manually created or with Relay (which I have not used yet) looks like already has this. | |
import { useAsyncResource } from 'use-async-resource'; | |
// ErrorBoundary refer to: https://gist.github.com/nevermind89x/910fddf9f09feccc38e04eb5ba1b8bca | |
import ErrorBoundary from '../ErroBoundary'; | |
// ../../placeholders/UserProfilePlaceholder.tsx | |
/** | |
* UserProfilePlaceholder | |
* @returns {JSX} | |
*/ | |
const UserProfilePlaceholder:FC = () => { | |
return ( | |
<div>Some generic placeholder</div> | |
); | |
} | |
// ../SuspensefulUserProfileProps/index.tsx | |
interface SuspensefulUserProfileProps { | |
userId: number, | |
}; | |
// We can use a function like this one, or can also just pass fetchUserProfile instead of fetchUser | |
const fetchUser = (userId: number) => fetchUserProfile(userId); | |
/** | |
* Suspenseful user profile to wait for data | |
* @param {number} [props.userId] Current user id | |
* @returns {JSX} | |
*/ | |
const SuspensefulUserProfile:FC<SuspensefulUserProfileProps> = ({ | |
userId, | |
}) => { | |
const [profileReader, ] = useAsyncResource(fetchUser, userId); | |
return ( | |
<ErrorBoundary> | |
<Suspense fallback={<UserProfilePlaceholder />}> | |
<UserProfile profileReader={profileReader} /> | |
</Suspense> | |
</ErrorBoundary> | |
); | |
}; | |
// ../UserProfile/index.tsx | |
interface UserProfileProps { | |
profileReader: () => any; | |
}; | |
/** | |
* | |
* @param {function} profileReader | |
* @returns {JSX} | |
*/ | |
const UserProfile:FC<UserProfileProps> = ({ | |
profileReader, | |
}) => { | |
const data = profileReader(); | |
return ( | |
<> | |
<h1>{data.name}</h1> | |
<h2>{data.email}</h2> | |
</> | |
); | |
}; | |
// ../UserProfileList/index.tsx | |
/** | |
* UserProfileList Component, wraps a list of profiles | |
* @returns {JSX} | |
*/ | |
const UserProfileList:FC = () => ( | |
<> | |
<SuspensefulUserProfile userId={1} /> | |
<SuspensefulUserProfile userId={2} /> | |
<SuspensefulUserProfile userId={3} /> | |
</> | |
); | |
export default UserProfileList; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment