React + RxJS = Reactive Global Goodness

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so umar asks can we do a video using react hooks and rxjs and absolutely we can on this blue collar coder viewer request video and if you want your topic covered be sure to put that in the comment section down below and i'll take a look at all the comments and i'm happy to do that and see if there's another good video in those comments now what we're going to do to test this out is we are going to build this cool pokemon deck builder app it allows you to go and search through a list of pokemon and then select them and that makes a deck out of them and we will manage all that state using rxjs which is a reactive state management system that was around way before react and is really well accepted in the community it's really cool so i'm happy to do a video on it one caveat though i am not and by any means an rxjs expert so if you have any hey you should have done this ways be sure to put that in the comment section down below and we can all have a chat about that i think that'd be really good meantime of course let's just jump right in and build ourselves a pokemon app using rxjs so i'm gonna go over the terminal go into the temp directory and i'm gonna do yarn create react app and we'll call this rxjs pokemon and i'll use the typescript template for that so we're going to be doing typescript okay let's bring it up in vs code the first thing i'll do is bring up the terminal and then within that i'll do yarn add rxjs i'm not going to use any libraries at the beginning to get react and rxjs talking together i eventually will there's a really good one that allows us to connect to observables and it's probably better than doing this by hand let's bring that up yarn start so there you have it the basic react launch screen let's go and pair this down a lot get rid of all of that stuff get rid of this class name don't need that i need that logo and let's go and change the css just a little bit to make the font sizes larger and bring it in from the corners [Applause] and also make our input fields big as well as the check boxes [Applause] and for this one make it with 100 cool okay so now i need the pokemon data and i've got some actual local pokemon data that i'm gonna drop in here of course all that is available to you in the code that's on github i'm just going to put that into my public directory and we'll take a look at what that looks like so this is just an array of pokemon where you've got the id you've got the name some types some statistics you know the usual kind of stuff now let's go and create a new file called store and that's going to be where i'm going to hold the global state here and one of those things is going to be that list of pokemon so how does rxjs store and manage state well it uses what's are called observable subjects so a subject can be any piece of data and observable means that its value could change over time and you could subscribe to it so you create the subject you give it new values using a method called next and then any subscribers see those new values as they come in now the type of subject i'm going to use is called a behavior subject and the reason i'm going to use behavior subject is because behavior subject actually stores its most recent value and makes it really easy to use so i need to go and create a new thing called raw pokemon to store that list of pokemon and i'll just do new behavior subject with an array but i really want that to be a typed array i want to actually have the pokemon data in there so i'm going to go and go over here to pokemon simplify i'll copy out that first one and then using a vs code extension i'll convert that json that's in the clipboard to a pokemon interface and this is right this has the id the name and all that good stuff so this is not going to be in any it's going to be an array of pokemon now why'd i put this dollar at the end what's that about well by convention in rxjs anything observable has a dollar as the suffix so it's just a nice way of knowing that that's a an observable thing you can do a subscribe on let's do fetch and then we'll do that pokemon simplified just get the right name here and then then get the response back as json and we'll do that next to say that here's the next value for that data and if we had multiple times we were going out and getting data we just keep doing next next next and every time we would completely overwrite the original value with this new set of data all right so that's probably good for a start let's go and export this so that i can consume it on the app side import raw pokemon from that store and i want to use use effect to subscribe to that raw pokemon so do a use effect that's going to take a function and when do we want it called well we want it called when the component starts up and to do that we use an empty array and then here we can say pokemon.subscribe actually send it to console.log there we go cool so let's go over here to our google chrome and now we got a blank page awesome let's do inspect and see what we get in our console okay so down the console we can see that we have an array of hundreds of items and they actually all have that data that's really cool so we first get an array with nothing in it which is the blank array that we created the behavior subject with and then we get the array of 809 items in it all of which have pokemon data in them now in the original app we actually had a power ranking for each one and the data that we get back doesn't have that power ranking in it so we need to derive the power ranking from that so we create a new optional field called power and now in addition to pokemon we'll create a new observable from raw pokemon so how do we do that well i'll create a new one called pokemon with power again dollar because observe observable and then we'll pipe the output of raw pokemon through a function that will give us that new power ranking so how do we define that function well we use a map and we get map in this case from rxjs and map takes that list of pokemon and then from there we're going to do another map because this is actually an array so if we get this this is an array of pokemon so we then can do a map on that and we'll take all the original pokemon data and then we'll create a new field called power that has all of this data associated with it so let's see terminate that terminate that terminate that and yeah there you go so the power is just going to be all of those stats added up so now if we export this instead of raw pokemon and we subscribe to that let's see what that looks like again we have this massive array and if i drill down in any one of these like bulbasaur for example we can now see that it's got a power ranking on it which is the sum total of all those statistics that's pretty good actually okay so let's close this out again so now we're seeing how the reactive part of rxjs works when raw pokemon changes pokemon with powers automatically updates because of this relationship between the two rxjs knows that the output of this pipe is then another observable pokemon powers that has all this data so whenever this changes this will change in kind it's really cool it's a nice way to model data that's similar in a way to what you get from a spreadsheet okay so the next thing to do is start building out that ui i don't want to keep looking at our pokemon through the console so the first thing we need to do there is build out the left hand side which is a search area which have you type in the search key that you want and it goes and finds the pokemon that have that name so let's go back into our app and we'll bring in use date so we're going to want to go and store that search value we'll create a new component called search and within that we will have a search field we'll create a div there and within that input we'll have that search field as a value like that and then we'll have the on change pretty cool so let's go back over to our app and actually we'll get rid of this use effect for the moment and we'll create a new grid here that has a two column layout and we'll put that search bar in there cool okay let's go take a look all right so we got a text field here now we need to actually show the pokemon down here so we need to use a use effect again and we need to subscribe to that pokemon with power but i actually think in this case we want to go and store the list of pokemon that we have in that pokemon with power so let's go and create a new local called pokemon has that array and then we'll do set pokemon when that changes now this is actually going to give us a subscription and we want to be good about unsubscribing so we need to return a function that calls unsubscribe when this component unmounts and now with these two we can do a used memo that takes the search and the pokemon and gives us the list of pokemon that we actually found so let's do use memo and then create filtered pokemon where the pokemon name includes that search value and it depends on pokemon and search now let's be a little bit better about this so i want to do two lowercase and also search to lower case that might make it case insensitive all right now we'll go down here and we'll create a div that has in it our filter pokemon where we map them and we'll give it a key and we'll put in the power there that looks pretty good actually i'll make make this strong so you can see the name over the power like that okay looking good now if i type in bulb ah awesome not bad okay cool so next thing we need to do is make these selectable and then whatever we select there will go on to the deck display that we'll put on the other side so we need another subject we need a selection subject that keeps the list of all the ids of the ones that we've selected let's go back over into our store we're gonna make that global so create a new one called selected again it's observable and we want to be an array of numbers not just a single number so there you go and we go down here to store and now we'll put in an input field type google's checkbox with the check where we look at the value because every behavior subject has a current value in it and we'll see which is going to be a number array and we're going to see if it includes the id of the pokemon and then when we do the on change we need to see if it's in the array and if it's in that array then we need to remove it and if it's not in the array then we need to add it so let's go do our on change so the first thing we need to do is go and see if it's selected so if the selected value includes that id okay so in this case we actually have that value in the array so now we want to do selected and give it a new value using next where we've removed that value from that array using a filter so we do the filter we get an id and if the id matches the one that we're actually currently working on which is p dot id then we remove it otherwise we let it go and then we do else and in this case we just want to go and add on the id into the array so we do next again to give it a new value and then we give it that original value plus that new id okay looking pretty good we've got all these check boxes in here now if we click them nothing happens what we do like for example bul and then bring it back ah okay so selected is actually getting changed but what's happening here is we don't have that connection to react we haven't done the use effect that we did up here to go and connect that selected with state now hmm okay we could do select it again we could create another use effect but i think what would be more interesting would be to actually alter pokemon to add on a the selected value and we'll go and add on selected which would be a boolean and we'll create yet another subject and this subject is actually giving me a combination of the original pokemon and the selected and then the output would be a new pokemon where the selected is true if it is found in that selected array okay so let's create a new one called pokemon i'll actually go and start with pokemon powers now pipe can actually run through multiple functions so the first function we want to have it go through is going to add in selected so what we can do is we can go back over here and we can say and we can say combine latest with now we can put that in as the first function in this pipe pipe has multiple functions it's going to step through every single one of them so now at this point we'll do map but that map is going to have the pokemon value as well as the selected value as an array just like that and we can use at this point again that map on pokemon to take everything pokemon but also give us the selected where it includes the id so now selected to be true if it's in this array right cool so now let's see over here on pokemon to get rid of pokemon powers and here now i've got selected so i'm just going to p dot selected cool very nice and now if i change this and i bring it back nice we can see that we actually have that so let's go back in here just one more time to see how this is working so pokemon with powers we are using that as a starting point and then we are bringing in the selected observable and then with that we have this map where we take that array we got these two items now in the array we got the original list the new list of pokemon and whether it's selected or not and then we generate from that a the pokemon array which is also observable where we've got this selected value and so whenever anything here changes pokemon power or selected changes we automatically update pokemon which is really cool so what do we need to export out of here we don't need pokemon powers anymore that's part of it cool but we do need a deck we want to go and have this deck over here so let's go and create another observable called deck and again we'll pipe and again we'll map and we'll just run the pokemon that we get from here this pokemon and say well if it's selected then it's part of our deck and otherwise not all right so let's bring that in and we'll create a new component called deck and we'll return from there like a h6 or whatever h4 that says deck and we'll just put it side by side now i could go back and do this use effect and manage that state and all that but in all honesty there's a better way to do this and that's to use this library called observable hooks so that's what we're going to do we're going to bring in observable hooks and this is a set of react hooks that makes it easier to connect with these observable subjects so let's yarn add that and we'll start up again now from that i'm going to bring in use observable state [Applause] and i can get dec by calling use observable state with that observable that deck observable so what is that type if i do a command k command i i can see that this is actually an array of pokemon awesome but one thing is interesting it's actually got undefined down here and that's because before you get any events emitted from rxjs we don't know what you might be so i'm going to say that the initial state here is just an empty array and that's going to make sure that this is always an array and therefore we can do a nice convenient map on it so let's wrap this in a div as we do with all things react dibs div divs and then we'll go through all that deck and we will key on the id cool and we'll put in an image nice and i'll also go and put in another div that's got a name and i'll make them a flex box to put them side by side all right now as i change this oh wow that was fast that's really cool but it's so cool to see the reactive nature of rxjs and react working together like this it's just it's really clean and you can see over here you've just got these declarative relationships between dac and pokemon and selected and this is all just completely platform agnostic at this point you could go put this in anything you put this in node.js or whatever you want this is a really nice way to model data and have everything react the way it should like in a spreadsheet okay so let's go back over to app and can we use this use observable state anywhere else sure well basically we have the same thing going on here with this combination of this use state and this use effect so all you do here is say use observable state again it's an array it's going to be just the pokemon and we'll just put it on pokemon [Applause] yep works great so now we can get rid of that use effect we can even get rid of this definition of pokemon kind of tighten things up a little bit here so if you didn't want to model this all as globals like this could you use context for that sure let's try out using context so we'll bring in now we'll actually make it a little bit more react specific so i'll go up here to import create context from react as well as use context and we'll create something called pokemon context using create context and we'll just give it everything we want in there we want the pokemon dollar we want deck dollar we want to select a dollar let's go and do all that and then we'll create a new component called pokemon provider which is a react function component and the reason we want that is we want access to the children because we're going to wrap things and we'll do that pokemon context provider we'll put in everything we did before just like that and then we'll put in the children in there and then we'll put in and we'll finish out pokemon provider like that great cool now let's go over here and bring it in we want pokemon provider as part of this and we'll wrap the app in our pokemon provider but we're obviously still getting these values from the exports and we don't want to do that we want to have that come in through context so let's go back over here to our store.tsx and i'll create a new custom hook called use pokemon and all it's going to do is use the context of the pokemon context so we'll go back over here into app and we'll get rid of all of these and just use use pokemon and then when we need them we can just bring them in deck dollar comes from used pokemon and let's see this one needs pokemon dollar like that as well as i think selected yep cool let's try it out yeah looking really good so now everything's provided by context as opposed to being a global export like that in fact we can go back over here into store now what can we remove we can remove a bunch of these exports like deck no longer needs to be exported selected no longer next exported pokemon you no longer be exported the only thing we need to export is maybe the interface not always cool looking good so can we take this up to the next level by using rxjs to manage basically all the state in the app and the only state we have that's not managed by rxjs is this little search field so how can we do that well we can actually use like a behavior subject for this state so let's bring that in from rxjs we'll bring in our behavior subject so how do we create one of those that's local to the component well one way to do it is to use a memo so create a new thing called search dollar which is a used memo that just creates a behavior subject and it never changes because we only want it once and now we can get rid of search and set search and this is this value and then we want to use that next cool but this filter pokemon now isn't going to know this search change right because search no longer exists so we need to actually do redo filtered pokemon using the same kind of thing so we use observable state again to basically regenerate filtered pokemon so create filtered pokemon using use observable state but in this case we'll give it a function and so the next thing we want to do is return an observable that we can then get the state off of so the way that we do that is we take pokemon and pipe it again like we did before and the initial value here is going to be an empty array just like before but we want to use our trick like we did with that selected where we had the original list of pokemon and we kind of added on selected in this case we want to kind of filter it down so we want to use that combine latest with and bring in that searches observable and then we want to do that map and that's going to have the most recent pokemon value along with a search value and we'll do basically just what we did before so let's do the two lower case again make the case insensitive now we need that map we no longer need that but this particular way of using use observable state actually gives us an array back so i want to take the first item off this array and that is the filtered pokemon then command k command i and there you go there's our list of pokemon so hit save jump on over here and yeah awesome so can we try the bulb again yeah works perfectly so now we can remove this and we've got a react app where all of the state is managed using rxjs even down into the actual component itself so you can make global component state using rxjs subjects and then you can also make component local state using rxjs subjects all right umar i hope i've helped you understand a little bit more about how to get rxjs connecting to your react application of course if you have any questions or comments be sure to put those in the comment section down below and for the rest of you of course you can also do the same if you like this video hit that like button if you really like the video hit the subscribe button click on that bell and you'll be notified the next time a new blue collar coder comes out
Info
Channel: Jack Herrington
Views: 4,087
Rating: 5 out of 5
Keywords: rxjs, react, reactjs, reactive programming, react rxjs, react rxjs state management, react rxjs tutorial, react rxjs example, react rxjs subscribe, react rxjs hook, rxjs react hooks, rxjs react
Id: s6nG0byDI-o
Channel Id: undefined
Length: 26min 46sec (1606 seconds)
Published: Mon Sep 13 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.