How to use RxJS with React Hooks

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
however now the going team here and today I want to talk about how to use rxjs together with react hooks this video assumes that you are familiar with react and feel at home with react hooks so let's start by talking about what is rxjs and observables rxjs is a reactive extensions library for JavaScript as it says on the website and it's essentially a library for reactive programming using observables if you are not familiar with all of those concepts don't worry we're gonna go over them in a minute now let's start by talking about what is observables observables is basically an idea of an in vocable collection of future values of events I like to think about it this way so you have a promise and promise can only resolve one time right so it can either be a rejection or fulfillment but it will only resolve once while observable have an option of actually sending more than one value or event over time and this is essentially what you have to know about observables right the cool thing is that observables are actually in process of getting standardized into ACMA scripts there's been some problems with the proposal and it's still stuck on a stage one but it's coming to the language sooner or later at least that's my opinion and there's like a lot of effort put in the proposal so if you're curious the links to all the websites that I'm showing are going to be in a video description if in case you want to check them out for yourself alright now that we got the basics out of the way let's just jump right into code sandbox and see how exactly do you use rxjs and observables in a standalone fashion right so I'm just going to create a new vanilla sandbox I'm gonna add our XJS here as a dependency and that's basically all we need so what we're gonna do is we're gonna implement a very basic observable that will show us the numbers right so I'm not I'm not even gonna render it in this case I'm just gonna import from from rxjs so this is the from operator allows you to create observables from other iterable things or in some other special cases like promises in this case we're going to create a new numbers observable right and we're gonna say from array and in this case is just gonna be numbers so very straightforward nothing super fancy here right now let's say we want to actually do something to those numbers right so let's say we want to have squared numbers so how would you go about that squared numbers is going to be equal now we're going to take our observable and pipe its to operator so called operators which is basically modification functions which is something we can import from rxjs slash operators right in this case let's say we also we are saying we want to squared numbers which means that we want to square them which means we need the map function right so we're gonna pipe it to the map function that takes in a value and then does something to this value since we're squaring them we're gonna do exactly that so it's gonna be squared numbers right now if I try to console.log this squared numbers we're actually not gonna see the numbers themselves but we're gonna see the observable this is exactly what I was talking about before so it's a primitive right now what do we do actually if we want to see the real numbers we have to subscribe to it so this is one of the things of the observables to consume it you subscribe to it right so we got the result and if we console.log the result in this case we're gonna see that we print out the values one at a time so this happens for each value right the whole pipe happens for each value it's also lazy this is like one of the strengths of the observables they are executed lazily which means that okay say we have this range say we want to filter so we're going to auto import the filter function from the observable operators and say we want to say okay we want all the values that are larger than two what the laziness means is that actually the square the map that we define here it's only going to be executed after the filter is done so it's not gonna do any work whatever the complex pipelines you have there after the filter on any of the values coming before that this is like one of the bigger things about the observables right this is the basic usage so it's very straightforward worth noting that basically once you subscribe you get the subscription objects and you can unsubscribe from it so say if we want the for some reason to dispose of it right so we're going to console.log the first number we get and then we're gonna say subscription dot unsubscribe which will result in us just getting the first number and then everything else again is going to be discarded and never executed because observables are lazy and if nobody is subscribed to them they're not gonna do anything okay so this is the basic case now let's talk about the usage of observables in react without hooks so like the you know the the old standard way of doing that so we gots the code sandbox for react here once again I'm gonna import rxjs and we won't actually be needing any new files here so I'm gonna just you know copy this code we have over here because let's just start with implementing the exactly same thing but rendering the numbers inside of our react app right so how do you go about that well in this case we got the function components so let's make it into a class stands react start components right and this is gonna be our render method and we need another closing bracket there we go okay so now we got the class rendering as expected so what do we have to do to work with observables well first of all we need to define a column sorry the estate because it will need to be updated so the our component has to react to the changes right I forgot the super over here and we're gonna say okay that current number is one for example I guess let's start with zero because we don't have zero in our numbers array right and okay so we define that we set the state so now we can actually render it let's create a simple render here current number is this states that come on state current number right so we got that now we need to actually listen to the observable so we obviously cannot just subscribe to it and never unsubscribe because they will lead to memory leaks and problems in the long term with the amp so that means that we have to handle two things we have to handle component did mount right so this is where we set up our subscription this is exactly what we want to do but instead of saying that let's subscription we're gonna say this subscription and store it on the component itself right and in this case we're not gonna unsubscribe here and instead of using console.log we're gonna set States to our current number result right so this is exactly what we want to do now this works we get our final number because the numbers are being set dynamically but the problem is that on every mount on every refresh on every page change for example this is gonna result in more and more listeners set right which is not something we want which means that we need to clean up after us so on component will unmount we're gonna say this subscription and subscribe not too bad right so it's it works but yeah it's not far from being perfect essentially right now let's make it more interesting so let's say we want to see the numbers dynamically here in G right so let's how do we do that well there is a delay function that that is one of the operators for HGS and let's say we want to see one number per second so if we do that you see it actually kind of works but it still shows us only the last number this is because the delay is applied to all of the values instantly right so we go through all of them and you set the delay for one second for each and while the delay is there it still applies it to every value which is not something we want to see so what we actually want to do is again one of the probably the most powerful features of our XJS is we want to merge map the value into a new observable that will be delayed so there's the merge map operator merge map right it takes the function that the value and returns something new so in this case we're gonna say that we create a new observable from an array that only contains our value so we're gonna pipe it into one second delay multiplied by the number so that the delay is increased every time right and as you can see here we finally have our result that is working so we actually can see on the page reload that the number increases over time right so okay we're skipping the value one and two in this case so the we're getting three four and five seconds delays but it works as expected right so pretty straightforward still that is a lot of code to set this up and if you would have to do that in every component that consumes observables is just not as convenient right so let's rewrite that to work with hooks first of all we're gonna change this into a function again right so we're going to have a function f that is this and it returns the renderer as before so this works perfectly fine this doesn't have to be a render anymore so we can just return this right let me just format this real quick now instead of this state and constructor we're gonna have you state hook so I'm gonna just use the current number and then we're gonna have set current number and this is gonna be use stage which is going to be equal to zero by default right so there's there we go there's our state now we have to figure out how to do the whole subscription on subscription again if you're familiar with the react hoax you know that there is a used effect hook that basically does exactly what we want so we're gonna do this and there's our use effect hook in this case when we want to run it once I'm gonna provide an MTA dependencies array because nothing really changes in this app right okay so we got the subscription setup well we have to change something we have to actually return the dispose function and we have to set the subscription to the local variable which makes it a bit cleaner and okay in this case we should use the current number over here and instead of this set state we're gonna use set current number so the code is even less verbose than before and as you can see here it basically works as expected so in a few seconds we should see our values start ticking there we go okay so as you can see it's a lot nicer when you're using hooks a lot less verbose you don't have to do a lot of setup and even better you can actually easily extract this use effect hook into a new hook let's call it use absorbs or use observable is what we want right and in this case we're gonna pass in an observable and we're gonna pass in a setter function because well observable has to set something right and I'm just going to extract this here and say okay so we're gonna listen to observable and use a setter function for the result and in this case since it's a custom hook it's gonna depends so we're not gonna run it once but we're actually gonna change it based on the observable and setter that are passed to it so in this case I can just write in my coat okay use observable we're gonna use square numbers and we're gonna use set current number right so once we say that we should actually see the numbers working as expected there we go okay so this is all nice and easy but so far you know it doesn't exactly seem useful right so we've been doing all those things and it's kind of looks nice a synchronous and everything but how do you actually apply that in real world well let's implement a real world example that is probably in showcased for well just about every possible rxjs demo I think Auto suggestion or you know search suggestion basic right so in this case I'm gonna use the Pokemon API so I got the URL over here and which is basically gonna have a function that fetches gets up gets get pokemon pokemon vine eight right so we're gonna have a function that takes in a name and it's gonna be a synchronous so it's gonna be a promise and then what its gonna do it's gonna fetch okay a weight fetch our URL so the one that I have this is the Pokemon API and it basically has 2,000 Pokemon so which is going to grab the whole array still seeing unison you know in reality you would have a proper API that does the search for you but in this case we're gonna in this case we're gonna simulate the synchronicity okay and then we're gonna get results as Jason and in this case it's gonna be results and we're gonna name them all pokemons right so we're gonna extract this and then what I'm gonna return is I'm gonna say okay all pokemons filter Pokemon so that Pokemon name includes our name right so basically just filter me everything that the API returns with the input that user provided right so simple enough now we don't really need all of that anymore so I can just actually kill that but that will break our app so I will not do that just yet now here's the thing let's implement the search first right so let's I guess we can just kill that because we're not using we're not gonna be using it anymore right so we're gonna have search and we're gonna have set search right so this is gonna be our inputs and in this case I'm just gonna create input type text placeholder search and then we're gonna have value search and on change is gonna be handle search change because we need to do a bit more than just set the function so sorry set the value right so get our set handle a handle search change it's gonna take an event and we're gonna get the new value this is gonna be events targets value and in this case first let's just set search new value right so this will basically allow us to type in stuff in the search box and now we have it saved to the state so it correctly updates now while this works and everything it's not exactly does it doesn't search for anything right so how do you actually do that well we need to create an observable and then we need to apply operators to it right so of course we could create a new observable on every or change but that doesn't sound effective luckily for us the rxjs has a very handy thing called subjects and in this case we can take a behavior subject that is gonna be our preset pipeline for the value processing right so let's create a new search subject right so I'm gonna say okay we got our new search object which is gonna have the default value that is equal to nothing right so this is our user I can actually remove all of that because we don't really need that we do need to use observable okay so we created our subject now what we need to do is say okay search subjects next right and say new value okay so we pass our new value to the search subject which means whoever is subscribed to it will actually get that value so I'm gonna create a new state which is gonna be results and set results and it's gonna be use stage it's gonna be an empty array because we're expect an array of pokemons right and in this case let me just do a div here and I'm just gonna json stringify results now to write so that we can actually see how it looks so in this case it obviously looks as an empty array now what we want to do is we want to use observable right and we're gonna use our search subject and then we're gonna use set results to update it right seems straightforward so once I start typing it should set the values which you know it works but that's not exactly useful right because we don't really do anything to that subject now let's create search results observable which will actually do all the work for us right so we're gonna take the search subject and type it into a new set of operators that will essentially search for the results for us right so first of all we want to filter the input so that value length is more than one symbol because we don't want to search for something very short and Hamor our server with a useless query is essential right next thing we want to do is we want to debounce time and we want to say okay we want to only execute this after users typing for 750 milliseconds this can be tweaked a bit but you know essentially if user changed his might need way of typing we want to wait for him to actually finish it next thing we want to do is we want to say that okay we only want to change if the value is actually changed so if user type something then changed his mind erased it but then change the value back again we don't want to do the same search right and once this is done we want to merge map in this case sorry merge map come on I want to map our value to a new observable that is going to be created from our get Pokemon by name promise right that is going to be searched by our value so now we need to obviously use this search result observable here and this theoretically should give us the result so if I go into the search box and search for pull bazaar there we go so we get our JSON now let's actually render it correctly because this is not very user friendly right so we're gonna take results I'm gonna map them into a Pokemon which is gonna be a div that has a key Pokemon name and then I'm just gonna render Pokemon name over here and it's gonna be it so very simple rendering in this case you know this is not focus of this video so I'm gonna be very straightforward with it so if we search we got the names of the pokemons and if you know if I start typing like crazy erasing it you can see that it actually only searches for the last bit so it never hammers the server it never does unnecessary work and this is basically what's really great about our exchange white this is basically it's I think we covered all the basic things here obviously they're XJS is pretty old library it's very popular there's a huge community around it so if you don't want to write your own hooks or if you're looking for something very specific there is plenty of existing libraries out there for react for example rxjs hooks that simplify working with rxjs quite a bit so if you you know if you're interested if you don't want to write your own hooks do check it out it might simplify your life that is it from my side for today thank you very much for watching and I see you next time bye
Info
Channel: LogRocket
Views: 27,563
Rating: 4.9377651 out of 5
Keywords: RxJS, React, React Hooks
Id: Urv82SGIu_0
Channel Id: undefined
Length: 20min 2sec (1202 seconds)
Published: Mon Oct 28 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.