Introduction to React Recoil (Experimental) State Management

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey how's it going everyone it's lee halliday and today we are learning all about recoil estate management library for react from the folks at facebook but it is experimental um in the video where they introduced it they said they have been using it for almost a year across 30 internal applications but it's very sort of early days for this library but the cool thing is it's pretty easy to use there's only about four or five main functions that you have to understand and it feels very similar to using hooks like we use state hook for example but what this would be replacing is shared state across your application so that would be use context mob x redux etc so it's not going to replace your local state where you can just keep using use state but the one you have to share across multiple components in your application this is the app we're going to be building it's a little uh shopping cart app where you can add some yerba mate or coffee to your cart so we'll just click this and it will add it in add some coffee in and that updates the card on the right then we can modify our shipping and the totals are updating below so we've got a couple things going on first we've got shared state because we're sharing the state over here on the left in this component and also over here in the cart but we're also doing some derived calculations we're computing values from our state for example the totals here they're a combination of the subtotal meaning all the items in our cart plus the shipping method i chose so this component down here is basing itself off of computations from two separate pieces of state so that's what we're going to be building and we'll sort of learn some ins and outs of recoil as we go so just save this to get us back to the starting point and we've got this create react app without very much going on but i have already imported recoil just so that you don't have to see me doing that in this video and i've set up the inventory that we're going to be using so it's just a hard-coded list of three items the yerba mate coffee and tea plus a hard-coded list of the destinations for shipping and then we've got this one component down here at the bottom app which right now is just returning a div that says app we're going to do everything in one file just so that it's easy to sort of wrap our heads around as we're learning this and to get started the first piece from recoil that you would want to use is this recoil route so this provides it's the provider it provides the state for the rest of your application so you'd want to only have one of these most likely and you'll want to have it as high up in the component tree as you possibly can so that the rest of your components below that are children can access and modify this state so recoil route here right in the app and in here we're going to create two components available items which these don't exist yet and then the cart so why don't we just start by declaring these so we've got function available items and we'll just return a div that has an h2 that says that available items and then we'll do the cart below that function cart return a div oops and in the div we'll have an h2 that says cart save that let prettier make my code nice and this is what we got over here on the on the right available items in cart so what we're going to do first is start just by listing the items that are available so that we can eventually add a button to add those into our cart so we're going to start with a unordered list and inside of there we want to iterate over this object so in my opinion the easiest way to iterate over an object is by using a function called object.entries where you pass in the thing the object you want to iterate over so inventory and that gives us an array of two things oops help if i spelled right that gives us an array where each element is the first element is the key and the second element in that array is the value over here so we're going to map that array so mapping here and in here each one as i mentioned is an array where we have the key so we'll just call that the id and then we've got the value which is name and price so we can actually extract that out and just say name and price like that so what we're going to be returning is the li that will have a key and inside of here we can put the name and then we'll put at the price so let's just save that and it's working we can make it uh fancy so i'm talking about dollar sign but we can also just say two fixed to get those decimals showing up properly for for money so with our available items being shown it's now time to add a button to add them into our cart state that doesn't exist yet we're going to create that in a sec so here's our button add and it is going to have an on click event that will fill out in a second so very nice so the way that you declare state in recoil and we'll just do it up here outside of our app at the top is you declare it outside of your components using this function called atom so we'll say our cart state is equal to the atom and when you declare an atom think of an atom as sort of one piece of state you need to give it a key so we'll just call it cart state and whatever its default value is so we're going to have it as an object and the way our state's eventually going to look is it's going to sort of mimic the inventory up here where we'll have like a except it will tell us how many um quantity we want for each of those items so here we'd want two year ba mates uh one coffee etc so that's our goal to to build a cart that looks like this so with our state declared as an atom here we can now come down here and use that and this will look and feel very much like the use state hook from from react so we'll declare that and we will say use recoil state which is one of those hooks or functions i imported at the top and what you pass here isn't the default value like you're used to with use date it is this variable cart state that we defined right up here so this gives us back the cart and set cart like this and now we can move into our button and worry about how to add one of these items into our cart state so we'll do that just by calling set cart and we'll take a copy of the current cart and then we have to add in the item that you're clicking add-on so because it's a dynamic key we can set this dynamically using squared parentheses so the id is going to be equal to and there's two cases we have to take care of um either it doesn't exist meaning it's gonna go from zero to one or it does exist already and it will just increment whatever value it currently has so we can check that here by saying cart at id so we'll look for its current value if it has one or we'll say that it's zero because it doesn't exist plus one just like that so it's hard to see whether it's working right so why don't we just quickly and we'll remove this later we'll put in a pre-tag where we'll say json.stringify our cart make it look nice so it's empty boom we get eight one two b one two c etc so with the ad working why don't we work on the remove and we only want to show the remove button if that item already exists in our state so what we can do is just say check to see if the cart has a value and if that's true we're going to render out the button over here for remove and when you click this button it will call the function and we now need to handle two different scenarios again because either um we're just decrementing the value by one so taking it from two to one but if it's already at one we need to just remove it entirely from our cart so why don't we start by just taking a copy of the cart so that we can tweak it without modifying the original value at all and we'll check to see first are we at the last quantity in the cart so if copy at id is equal to one that means we're we want to remove the last value so we'll say delete copy at id if that's the case to remove it from our object and then we can just set the cart to be the copy that now has had that value removed we'll put an else down here which means we're just decrementing it by one so what we can do here is we can say set cart we're going to we'll just work with the copy but we will decrement it by one so copy it id minus one let's test it make sure it's working before we move on so i add one i remove it it's gone add a couple it decrements and then removes itself so you may be wondering why this blue flashing thing um in my react tools here i have it set to like flash blue whenever a re-render is caused and that's one of the advantages of using recoil it minimizes the number of re-renders and i'll go into that in a little bit more detail later and explain why that would come why that would help versus something like use context for example but because we only have one piece of state it's hard to really demonstrate that right now so why don't we now move over to our cart and we'll just display the values over here on the on the right so inside of cart i'm going to create a component called cart items and we'll create that cart items so in here we want to basically just get a read-only copy of our state of that cart so we can iterate over it and show the the items in our cart right here so we will do that by saying const cart equals and we're going to use another hook that we imported and the one we're going to be using is use recoil value so you use this when you don't want to set or modify your state at all you just want to read the value from it and we say use recoil value for our cart state variable and now we have access to it and this component is now subscribed to this state so anytime it changes it will automatically trigger a re-render so here we can do why don't we say if object dot entries for cart or we can even just say the keys length is zero we'll just return a p that says no items oh boy like that okay what did i do oh it's keys not key there we go so no items so if we get down here we know we have items so we'll put them in another uh unordered list that we want to return so we're going to iterate over our cart so it would just be object.entries and the entries are for the cart and then we'll map those so we get given the id plus the quantity because that's the value that we're storing in our cart and we want to return an li as a key of the id and then in here we want to put the name of the item plus the uh the quantity so because we have the id we can access the name of it by just reading from this inventory object up here so we can do is say inventory at id get the name times the quantity like this so we add one and then we get yerba mate times one showing up here on the right add a few more remove them and you can see it flashing blue as the state changes it's triggering a re-render of this component over here so that one is done i didn't want that why don't we just remove this pre here because we don't really need this anymore so save that cool so the next piece of functionality we're going to add is um to allow the user to change where the item gets shipped to so we're going to create another component called shipping it will go down here and shipping needs its own state so before we get to that we'll get to that in a second we are just going to show the three different um the three different destinations that you can ship to so we will return um we don't even need it in a ul this time we'll just return a div we're inside of this we will iterate over the destinations so again object.entries for the destinations we'll map them and we're given two things we're given the country which is the key and the the price or the cost to ship to that country put that around there and we will return a button so our button will just say the country and then at the price perfect so us is 25 bucks canada is 35 etc why don't we give it uh an h2 this is shipping perfect so now we need to add state to to store which one the user has actually selected so we're going to go up here at the top and we're just going to define a new piece of state so const shipping state is equal to an atom again which has a key of shipping state and a val a default we'll just say we start it to the us like that so down here in our shipping component now we can read in this state by saying const shipping and set shipping is equal to use recoil state passing in our shipping state atom that we defined above and now what we can do is come down here and we'll say if the country that we're iterating over is equal to the current shipping why don't we show a span that has a check mark in it actually spicy pepper why not otherwise we'll just say empty cool so there's our spicy pepper why don't we put a space before it like that so that's showing our current one which is the us but we need to add an on click event to change its value so in here we can call set shipping and set it to country just like this so now when i click canada it pops the pepper over to canada columbia u.s so now is where i can start to show that um the cool thing about recoil is because you have like little pieces of state as declared of these atoms whenever you modify them it's only triggering re-renders on components that have subscribed to updates from those atoms so when i change the shipping you see it's only modifying this and when i change the available items it's modifying this plus this but not the shipping if we would have done this using use context and we had one single context that had both the cart and the current shipping because they would be both reading from the same context it would be triggering re-renders on all of those components whether or not the value had actually changed in them so you could solve that by having two different contexts but that's now getting a pain imagine if you had 10 different pieces of state and you had 10 contacts 10 providers it would be a little bit of a nightmare so this provides some advantages in that sense the last thing we're going to be doing is showing the totals down below which will be a combination a computed value of multiple atoms multiple different state values so we'll create our function called totals which will have a div that has an h2 of totals that we return cool we will put this into our cart like that and now we're going to work with a new piece of functionality called a selector so we'll say totals state is equal to a selector so a selector is different from an atom and that this is a computed property based on other atoms values it's not state itself it's just sort of like a read-only computation you still need to give it a key so total state except you don't define a default here you define a get and this is a function that receives a function called get and then it's our job to basically return the computed value of that so what we can do is we'll just start it off by we're going to return an object that has subtotal we'll just put in dummy values for now a shipping value and then a grand total so we need to find these values here so we find these values by using get so what we can do here is we can say get the cart by saying get cart state um get the shipping from get shipping state so we could start to fill these in by uh saying destinations at shipping country is the shipping cost why don't we put this into a variable const shipping total is equal to that we need to calculate the subtotal so we'll do that by using um a reduce sub total so what are we going to reduce we're going to take the cart and reduce all of the entries in it so we will say object.entries for the cart we're going to reduce them so reduce is a function that we'll get to in a sec but our default value will be zero and then as we iterate all over all of the items in our cart we'll start incrementing this total value here so to reduce we're past two things we're past the current accumulated total and then the second one is the item that we're iterating over so because we used object dot entries this is an array that has a key and then inside of uh the the value side we have our quantity so down in here did i do this right hopefully we'll see what's it telling me expected a return value cool that's fine so what we're going to do is take our current total the ack and then we're going to add in the price of the value times by the quantity so we can get the price by saying the inventory at the key or we could say the at the id multiplied by the quantity okay so now we have our subtotal we have our shipping total and our total total is our subtotal plus our shipping total cool so that was a bit of a mouthful especially this reduce here i have an entire video on reduce if if reduce sort of trips you up a little bit i'll link to that in the comments below and in that video we went over 10 different ways you can use reduce so it should give you a good overview of of how reduce works so now that we've set up this select selector which uses a computed value of our two different atoms our two different pieces of state we can come down where did i declare this thing i'm going to move this down closer to the totals like that we can come down and because we're just going to be reading from this selector value we can say const totals are equal to use recoil value and it's the value of total state and at this point inside of totals here we have this value that we returned from our selector and the cool thing is this is subscribing to any changes to either the cart or the country that we're shipping to so it's looking for those two values to change and when they change it will trigger a re-render of this totals component below because we're subscribing to it by using this use recoil value inside of here so why don't we say the subtotal subtotal is equal to dollar sign totals dot subtotal and we can just say two fixed to get it looking nice perfect so it's zero if i were to add one oh damn not a number that's bad so i did something wrong but what did i do oh i know this the inventory at the id is this entire object here i don't want the entire object i want to multiply it by the price i think that's the issue dot price not a number all right there we go 10 bucks cool so as i add more it's multiplying by the quantity and um it can add more different items to the cart and you can see the blue little border showing up that it's updating here below so we'll just do the same thing for the shipping and then we will do the same thing for the total but total is more important so we will make it bolded by wrapping that around the total cool so we'll add some yerba mate tweak our um shipping we'll send some yerba monte to colombia and then down here on the bottom we've got the total showing up so no matter which piece of state i'm changing either the shipping which triggers a re-render of just these two components or the items in the cart triggering a re-render of the cart and the totals but you can see that it's not triggering a re-render of this shipping here so i think one of the main reasons they created this library recoil is because imagine you had like a thousand different items that are all updating independently you don't want to have to create a thousand providers and contacts so you can tweak them without triggering re-renders but you also don't want to have all a thousand in one single piece of state because then anytime any of the thousand items change every single component is going to re-render so with recoil you could have a thousand atoms and you can tweak those atoms independently and it will only cause re-renders on the components that have subscribed to changes for those atoms so that was it for today we've got um recoil from start to finish we covered with the recoil root atom which is your state selector which is for computed values from your state use recoil state is when you want to both read and write to that state and use recoil value is when you just want to read a value hope you enjoyed the video take care bye
Info
Channel: Leigh Halliday
Views: 7,429
Rating: 4.9861593 out of 5
Keywords: react tutorial, react recoil, react state management, recoil state management, recoil tutorial
Id: wHe6-2-ZX6Y
Channel Id: undefined
Length: 27min 49sec (1669 seconds)
Published: Sun Aug 30 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.