Skip to content

Instantly share code, notes, and snippets.

@nevermind89x
Last active September 1, 2021 00:25
Show Gist options
  • Save nevermind89x/eb9df19b4f1f02c15a0d16bce303fc60 to your computer and use it in GitHub Desktop.
Save nevermind89x/eb9df19b4f1f02c15a0d16bce303fc60 to your computer and use it in GitHub Desktop.
Contra Suspense Code
/**
* 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