Created
July 29, 2021 00:16
-
-
Save avastamin/554b7b1ef6dc4220c02b361d847a45b4 to your computer and use it in GitHub Desktop.
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
https://gist.github.com/avastamin/a254506a97374c921d9bd4e086ff7ef2 | |
/** | |
* In this short assessment, the following code tries to implement the React Suspense API, | |
* but does so incorrectly. There are 3 core issues with how these components utilize Suspense and concurrent mode -- can you find them? | |
* | |
* In your submission, be sure to: | |
* 1) Clearly identify what the 3 core issues are, and how they violate the principles of React Suspense; | |
* 2) Write and submit the code to fix the core issues you have identified in a gist of your own | |
* | |
* If you aren't familiar with Suspense, the docs are a good starting place: | |
* | |
* https://reactjs.org/docs/concurrent-mode-intro.html | |
* | |
* We rate each answer by comparing the submitted answer to how we would write the same code in production at Contra. | |
* You are guaranteed an interview if your code ticks all the boxes. Good luck! | |
*/ | |
/** | |
* Problems are indentified: | |
* 1. No fallback for suspense which is bad UI because users dosent' know why screen white and empty. | |
* 2. ErrorBoundary was missing becuase fetching does not work then we need display | |
* 3. data fetching at useEffect might cause race conditions and waterfalls. To avoid that it's recommented to fetch data | |
* outside a component. | |
*/ | |
import { Suspense, useState } from 'react'; | |
const initialResource = fetchUserProfile(0); | |
const SuspensefulUserProfile = ({ userId }) => { | |
const [data, setData] = useState(initialResource); | |
return ( | |
<Suspense fallback={<h1>Loading profile...</h1>}> | |
<ErrorBoundary fallback={<h2>Could not fetch posts.</h2>}> | |
<UserProfile data={data} /> | |
</ErrorBoundary> | |
</Suspense> | |
); | |
}; | |
const UserProfile = ({ data }) => { | |
return ( | |
<> | |
<h1>{data.name}</h1> | |
<h2>{data.email}</h2> | |
</> | |
); | |
}; | |
const UserProfileList = () => ( | |
<> | |
<SuspensefulUserProfile userId={1} /> | |
<SuspensefulUserProfile userId={2} /> | |
<SuspensefulUserProfile userId={3} /> | |
</> | |
); | |
// Error boundaries currently have to be classes. | |
class ErrorBoundary extends React.Component { | |
state = { hasError: false, error: null }; | |
static getDerivedStateFromError(error) { | |
return { | |
hasError: true, | |
error | |
}; | |
} | |
render() { | |
if (this.state.hasError) { | |
return this.props.fallback; | |
} | |
return this.props.children; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment