Instead of just returning a value from a recoil selector, you can return any promise, which means that you can do asynchronous functions in recoil selectors (this is a little like a redux thunk).
The huge bonus is that you don't have to do anything different when actually calling the selector - use can use useRecoilValue
in the same way that you would from a normal selector.
The only thing you must do is somewhere in the component tree, wrap any component that uses an async selector with a <React.Suspense>
tag with a fallback
prop that will tell React what to display when the async selector isn't loaded yet.
Chris Achard: [0:00] have a synchronous selector here and the Git function returns right away.
[0:05] This can be asynchronous as well. If we come down here, maybe we fetch our highScores from a server. We can rename this highScores, make sure it's exported. Instead of returning right away, we're going to return an await, which means this function here has to be async.
[0:23] Now, get is an async function. We're going to return an await and we're going to make a new function called fetchHighScores(). Let's make that function here. fetchHighScores is going to be an async function. This can be any async function we want. In a real application, we would be fetching from a server. Here, we're just going to return a new Promise.
[0:47] From here, we can set a Timeout to simulate a network call. Set that timeout for one second. From here, we're going to resolve with the high score of 303.
[1:03] We can use this highScores selector just like any other one. If we go to our app.js file, we have Score here. Let's make a new HighScore component. We have HighScore, HighScore. Now we need to make a new HighScore file. We have to touch src/HighScore.js.
[1:27] Then we can open HighScore. This is going to be a lot like the Score file here. Let's just copy that and remove what we don't need. We don't need our atoms. This is going to be called HighScore. Let's just delete this for now and this. We're going to export HighScore.
[1:49] Instead of those atoms, we're going to import from that selectors file. We're going to import this highScores selector. Back in HighScore, we're going to import { highScores } from './selectors'. Then we can use the recoil value pull out the current value.
[2:06] We're going to say our score is the useRecoilValue(highScores). This looks identical to how we did it in score even though it's asynchronous. We can say High Score: {score}. This will wait on highScores to finish, return here, and then print the score.
[2:24] There's just one more thing we have to do. If we go back to App now and we try to use HighScore, then it's going to throw an error because we don't have a suspense fallback. Because this is asynchronous, so we need to tell React that it is asynchronous and what to show when it's waiting.
[2:40] We can say React.Suspense, and we're going to define a fallback, which takes a component, so for now we're just going to say "Loading..." and wrap our HighScore in that Suspense.
[2:56] If we save, it says "Loading..." for a second and it shows the High Score. If we reload again, it will show "Loading..." and the High Score.