Watch on YouTubeThe player loads when you press play.
In this video
What happens if a selector discovers a dependency after an await? In the first example, a selector fetches a user and uses the result to decide what to read next. Recoil has to track that second dependency so it can run the selector again when the value changes.
The second example uses a diamond-shaped dependency graph to see when downstream selectors run. I also cover performance changes and other updates that shipped in April 2021.
Try the examples in CodeSandbox.
Read the automatic transcript
YouTube generated these captions and sometimes gets names, punctuation, and code wrong. Check the recording if something reads oddly.
0:00 — hey folks so recoil 0.2.0 was released recently and i had to read through the blog post and some of the things that they mentioned in the blog post didn't quite make sense to me and it's because i don't think i've actually encountered any of the bugs that they've fixed but going through it and actually trying to figure out some real life examples has taught me a lot about recoil and has made me think about some extra possibilities of what you can do with recoil so let's take a look at the changes and have a look at what is now possible in recoil 0.2.0 but before we dive in if
0:31 — you find this video helpful please hit that like button it helps me out a lot as a youtuber who's just starting out so let's dive in on the surface there isn't anything drastically new or different in recoil 0.2.0 this update is more focused on improvements to certain edge cases so to start with the whole selector implementation has been completely rewritten this has fixed some prior issues with selected behavior and the first is that you can now add a dependency to your async selector
1:01 — while it's pending so let me show you what i mean by that let's head over here to this code sandbox that i created showing off some of the new possibilities with request 0.2.0 so we're going to look at this one selectors can add dependencies asynchronously so let's take a look at what we've got so we have this current user selector which gives us information about the current user and basically what we do in there is it's an async selector and we get the user and then based on that user data and we're getting this from let's say an api
1:31 — based on that user data from the api we then fetch their friend using a different selector by their friend id and then combine the information so that down here in our component we can display the user and the friend but you'll notice that we're asynchronously adding this dependency of the friend selector to our current user selector because it's after this await and previously with other equal versions this didn't actually work so let's quickly head in to this demo you can see that it's loading and it loads in just fine we get the
2:01 — user and we get the friend and it renders out perfectly fine but if i actually go here and i change the recoil version to previous version you'll see that it just loads and you can see that get current user actually kind of loops it keeps running this is really cool and it opens up a lot of extra possibilities when you do stuff with async selectors and this rewrite also ensures that when your asynchronously added dependencies change no matter when they were added
2:31 — the entire selector will actually rerun and there are a few other edge cases that were previously broken but are now working with the new selector's implementation such as making sure that when you have a bunch of selectors in a diamond dependency pattern for example or a kite dependency pattern that only the selectors that need to rerun actually rerun so here's an example of a kite dependency structure so we have some states at the top and then we have two other pieces of state and these would be selected
3:01 — and these two depend on this piece of state and then this final one depends on all three giving you a kite pattern if this dependency state only depended on these two then you'd get a diamond dependency pattern right so let's actually look at a real life example of this so if we head back into our code sound box and head over to the diamond dependencies one you'll see that we have a an atom which is the an atom which is the top
3:33 — level state that we looked at in our diagram and then we have two other pieces of state chakra ui state and material ui state and then a final selector called app dependency state so what are we doing here so if we open up this page you'll see that you have this little drop down over here where you can select between chakra ui or material ui you can choose which one you want in your app let's say and then we get back a dependency string of which packages to install so if i switch to material ui you'll see that we get
4:03 — material ui logged out so let's look at the code for this so at the top level we have our app config state and this stores which ui library to use and whether or not we want to force a specific low dash version and this is the state that drives our drop down over here and then both chakra ui state and material ui state depend on this app config state because they need to know when they set their sub dependency for low dash they need to know whether to set the version to the force to low dash version
4:34 — or to the latest one and then finally same thing for material ui state and then our app dependency state depends on our app config state because it needs to know which ui library to actually add to the dependency array and then what it does is depending on which one you've selected from the drop down it either gets the chakra ui state selector or the material ui state so we have changing dependencies here and this is what gives us our diamond dependency pattern for example
5:04 — and what we do here is we just combine all of the dependencies into one string so that we can pass it along right so what you would expect is the first run you would run the app dependency selector which would depend on app config state over here to get the url library and then we would get chakra ui and then this selector would run chakra ui state right and that's exactly what happens we get run app dependencies and then run chakra ui selector and then when i change to material ui what we expect to happen
5:34 — is that when we change the atom this select is going to rerun because we're going to get a new ui library and then instead of depending on this chakra ui state we're going to remove that dependency from the selector and add this material ui state instead now what we then want to happen is that this material ui state runs once but we don't want the chakra ui state one to run because we're not depending on it anymore so it's not needed but previously in recoil this chakra ui state selector would still rerun because it still depends as well on the
6:05 — app config state so app config state would change and then chakra ui would rerun and this would rerun even though the chakra year one doesn't have to rerun because we're not depending on it anymore we aren't using it at all so what we would expect to happen now is that the chakra eye selector doesn't run at all because we don't care about it when we switch to material ui only the material ui and the app dependency state should rerun so let's check that out and as you can see here that's exactly what happens so that's diamond dependencies and like
6:36 — i said there are a few other edge cases that this rewrite has solved and if you're actually interested in what those other edge cases are you can head over to this pull request on the recall repo and you can see a list of all the tests that were previously failing but that are now passing because of the new selector implementation and if you want to know exactly what these tests do literally just copy the name of the test and search it in the repo and you'll be able to see it over here so let's jump to this one for example and here you see selector is able to track dependencies discovered asynchronously
7:06 — which is that first thing that we looked at right and then you can see the whole test here to see sort of a bare bones example of the specific case and recoil is also now much faster so for recoil to work it needs to store the atom values somewhere right and now they're storing it in a high performance data structure called a hash array mapped tree and don't ask me how they work all i know is that it's a lot faster and this means that recoil can now read and write atoms much much faster than before and this probably won't show in most common use
7:36 — cases but when we're talking about like tens of thousands of atoms you really feel the difference so here's an example so if we head to our performance file you can see here that we have 50 000 squares rendered out and each one has its own atom so we're talking about 50 000 atoms over here so let's head to that you'll see that the page freezes up a bit just because it's takes a while to render out 50 000 react components but once it's loaded you can see that actually clicking the squares which when you click it changes the
8:07 — selected value of a given atom is really fast and basically what recoil has to do here when we change one of these atoms is it has to go into this map with 50 000 atoms pick out the one that we've changed and make a change and then it has to pull that new value back into react and as you can see this is pretty damn performant for 50 000 atoms and recoil now also has a new logo which i think looks great and you can check out their new site design at recoiljs.org
8:37 — there are also a few other small improvements and changes which i'm not going to go into detail about in this video and it's because these things i haven't yet covered in any of my videos or in my recoil course but i plan to make content about them in the future and then i'll cover it nonetheless there are a few notable changes the one is that now when you throw any non-promise from a recoil selector so not just an error the selector will go into an errored state this means that you can now throw a regular object if you want to handle errors that way for example and finally recoil is now
9:07 — compatible with ie11 but if you still need to support i11 then all i can say is i don't envy you and in terms of what's upcoming the team are working on some more performance improvements and this includes memory management which is going to automatically discard any unused atoms and selectors if they're not being used because currently as soon as you use a recoil atom and it initializes or recoil selector it stays in memory if you have an app where you're mounting a lot of atoms and then you navigate away from the page that uses them and you don't need to use them
9:37 — again there's a potential there for memory to creep up so that's going to be a really cool feature so that's been it if you're interested in following along with all their progress you can check out the recoil github and keep an eye on the issues and pull requests going in and i'll also be posting more videos like this as significant recoil versions are released and if this video has been helpful please do give it a thumbs up like i said it helps me out a lot and if you're interested in learning more about recoil and you haven't checked out my free recoil course yet i highly encourage you to do that it's
10:09 — filled with hours of free content that will help you use recoil like a pro go check it out at learnrecoil.com thanks for watching and i'll see you in the next one cheers
Originally published on Jacques Blom.

