React Hooks SWR: Fetch, Cache and ReValidate server data with SWR and Axios

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello youtube my name is Bruno and today I'm going to show you how to improve the user experience of your application using simple tricks for example caching HTTP requests for that we are going to use SWR if you want to follow along and create this application with me. I have the link in the description the SWR documentation is also in the description so this application as the name implies is like a JIRA ticket. We have comments and we have an input field where we can type something add a comment and hopefully in the future we will be able to update this table so let's jump into code our add comment is just a form with one field and a submit button if you watch the video from last week about farming this simple code looks probably familiar if you didn't it's okay what's happening here is every time I click on my add comment this one submit function will be called so this is the place where we need to do the call to our server in order to post the data so in my case I will use axis but you are free to use fetch or any other library you like so let's do these local host 4001 slash comments I think that's it the URL and now the last thing we need to do after importing excuse okay is to mark this function as a sink and on top of that saying oh wait here because this post will return a promise for us okay so now that we have that we can go back to our page okay we can probably even refresh this page just to make sure that everything is fresh and let's say that we do hello world for example another typo good job Bruno so doing that and going back to our mock server refreshing our mock server we can see that we have that hello world with that weird typo but it's there okay our next step now is to go to our table and do a real HTTP call in order to get data from our mock server so let's do that let's go to our on page here and our on page as I said as completely art coded data so we can remove this one okay and do the following we need data a function to set the data and we will use state from react so by default we will pass an empty array but then we can use an effect okay okay so let's just import this state I don't know use effect yes use effect is already imported as well and if you don't know I will just let you know that you can't do this okay these will have weird behavior so well vs code was already saying something so what you have to do is to say async function let's call it load data for example okay and before I forget let's just make the load data there and so what we need to do here is to do a get in my case again using axis so let's do Axios a white and why did why did vs code move my axis to capitalized I don't know but we can just do these copy-paste and now put again our URL so comment okay if you are asking your yourself why I'm doing these all the time by the end of the video I will create a base URL for axis so I can remove that from every single endpoint but for now I'm just keeping it there okay so in axis now we will have a response okay and this response will be an object and the real response that we care about is inside data so let's do this data response dot okay now if we go to our page everything should just work as we expected so coming here and we already have the data from the server it means the browser or freshed by itself and we can do something else another ello with a lot of foes okay we can comment the server already replied but as you can see our table is not updating yet because we are just doing the initial call when the component is initialized and that's it we never redo the call so we could have a lot of ways to solve it one of the ways is for our component here the Add Comment to have an output function okay or an event function that will just trigger that event and then here we know that the event triggered so we will change something that we will put in the dependencies of the use effect and the use effect will trigger again but it's already too many things right so it must be a better way to do that and I'm glad to inform you that yes there is a better way but before we do that better why I want to show you something else in this normal approach so let's kill our mock server okay oops sorry for the sound let's just kill our mock server go back here and say that the default timeout or the default de life from our mock server is no longer 10 milliseconds but two seconds okay so now for every post get put delete our server will take at least two seconds okay so let's just restart our mock server this one should be fast to restart yes it already restarted so going back here refreshing and you will see that our table will take roughly the two seconds to load now watch this and this probably happens in your application today you go to a different page okay and going to a different page and coming back to the previous page you are reloading the data you are not caching that data so in this case it was only two seconds but imagine that this call will take ten seconds your user will have a completely empty screen for 10 seconds can we do something better yes we can so let's come here back to our own page delete all of the code we created okay so I will just copy this bit I will just copy this bit because I'm tired of typing it all the time so what we need to do we will do data and now we will use a new hook that was done by the same exact people that the the next Jes or create an XJS so let's just import this this one so import these from SWR okay now with this we just need one more parameter because by default SWR is completely agnostic in which library or which factory you use okay you can use fetch you can use axis you can use as I said before any other library so they require you to pass here or in context I will put it here first and then put it in context because it's much easier to use in context ok so if you want to pass a function for your fetcher here it will be something like this okay so now we have excused we pass the URL then because we can use axis as a promise and this is again the same thing I did before okay so in this case I just need to import axis from axis again and this should just work for the first time we will left caching so going back to our browser okay fair fair fair so now our data it will be undefined by default okay so the first time we receive data this data can be undefined and yes it will be undefined for us so because we are using typescript 3.7 we can do just this okay if you are not you can do something like this and you are safe as well okay oops sorry you can do these in the you are safe as well so whichever version of typescript you are using you can do one or the other okay but because we have you in 3.7 we can just do this it's nicer right so going back to our browser you will see something quite nice I click now in add comment okay I click in ohm and I already have my data because it was cached by SWR isn't it amazing I think it is so next step that we can do is coming here and remove this from here because if we want to use a lot of use SW ours in a lot of components having to pass this all the time is painful trust me it's really painful so how can we avoid that and just have this clean call ok we can come here and because this is the next Jessup location I will just put it here ok and SWR coffee yep value equals to I think they call it affection yes they do ok ok it seems good let's just close this one copy it here and close it over there the last thing we need to do once again is importing axis so import Axios from axis okay and now we are passing this as a context and this is on the top level of our application so every single component will just receive this specific feature ok if you prefer to use fetch as I said before you put it there and it will just work so coming to our application and refreshing ok we now should be able to see our data and everything is just working as before the same thing we can come here ok come back and the data is there ok and as you see here every time we go away and we come back oops I didn't click and we come back in reality SWR is doing the call you can cancel that if you really want to you can cancel that but is doing the call again for things like this imagine that I go to another page I copy this ok and let's see this I say hello from another tab okay I click okay perfect I go back in time and another fetch happened because this this this window is now on focus and every time you regain focus SWR will trigger a new call and that's really powerful you can cancel that okay if you really want to you have a lot of options here that you can just cancel for example imagine that your component does two times the same call in less then I think the default is two seconds but let's say in less than 10 seconds so you just do one call and what's this did you pink so if I come here okay and I do this okay I can do this as date one it doesn't even matter those names okay yes date two and two times is just good enough so if I do this okay you are probably expecting as WR to do three calls but no because I'm passing this bit here and saying did you ping interval of 5 seconds so the same call to the same endpoint in the next 5 seconds it will not be repeated we will use the first one okay so going back to our page if i refresh you will see that I only do one call to comments okay even though I'm using it three times and this can be quite powerful if you have it in different components for example imagine that someone from business and by the way I said these this is two seconds by default so I think is a good enough default imagine that someone from business comes to you and says hey look Bruno we really really need in the add comments okay to have one new property that says how many comments exist in the application at the moment and you will be like well my endpoint doesn't return that well but we need it now and it happens quite a lot right and so in most scenarios you will be like screw it I need to change a lot the application or I need to just repeat the : without land right that's the two possibilities that you have but here you don't need to worry about that you can just do this okay even though we are in completely different components right let's do react that fragment or even putting a div whatever you want to use is not important right now so we can just say number of comments and we can say data that that went oops I needed thing here okay so we can just copy these close our forming with that div and now if you go back to our browser I just need to import this will vs code nope doesn't help it's okay SWR okay so now when we go back to our browser in a normal scenario if we were not using SWR you will be a bit sad with your job because you will be doing two codes for the exact same data well not anymore so SWR kinda saved you right so you can come here and we only did one call and look you showed over there the seven so it's quite powerful what you can do with that I'm not saying for you to not create your API endpoints properly and just do a bunch of calls in every single component but it can save you in a really delicate situation it can save you because in reality you didn't create any problem for your users you still have just one comment call okay so it's quite powerful so the next thing we can do is the delete and in the ohm we have a delete but even before we go to the delete it will be quite nice for us to do a comment and immediately after we do the comment dist I will update right it will be quite nice so let's go there let's do that one first let's come here let's just delete this alert okay because with that alert we lose focus of the window so clicking the table behind the scenes will just refresh okay I can show you that now when we do something for example I I can click it's finished okay and this type of no longer updates because well SWR has no way to know that it updated so in order to do that we can come here and use something called trigger event I guess let me just check I think it's trigger yes three okay and what is this trigger this trigger in reality is something that we can do like that okay and we just pass this bit here and what we are telling SWR is hey please something changed on on that endpoint so please go ahead do another HTTP call and update the cache with that new color right and this is already a good start let's go to our page and now you will see that it will update both these and the list here so let's say last option I think is a good name like any other and when this is finished okay my mouse when it's finished you will see that we did another call to the server right and you can see that the nine here updated and my last option here updated this is really powerful because it even allows me to go to another page and we are doing the same call there right so we can say hello world xxxxX for example just to be different ok now it updated there so we can go home and it's already updated for those as well ok this is quite powerful but we can do even better so let's do this even better instead of saying trigger we can use something called mute I guess I think it's muted or muted state yes we're tight ok and what is mutating in in reality mutate is a bit a bit stronger let's say it that way then trigger trigger you are just telling SWR to go to your server and then a plate cash in mutate you are mutating the cash first and after you go to the server and apply to your cash so it's much more of what's called the optimistic UI so you are just trusting blindly that your server will do what it will do and you applied immediately your ey it's a bit what Facebook does in likes you click the like it immediately happens right so they don't wait to go to the server to come back and only if the response is true or valid response they update the number of likes no they update immediately I think YouTube does the same thing so we can come here and we will see that mutate receives a key and the data that we want to do and on top of that if you don't want to revalidate oops sorry if you don't want to revalidate you can even say hey trust me just don't revalidate it it's okay don't revalidate in my case I want it to revalidate but in here we can just do the following so data okay and we can just say something like this okay so my comment which is values oops values it's over there and you will see that the ID is not there yet but the user experience is much better than not updating at all right so let me just clear our cache of our database because my mock server saves everything in a JSON file so let's just revert to have a smaller list to see it happening okay I saved and now going back to our page we will have this here so let's give it a try and say hello world once again add comment and ah I know I made a mistake okay I have a mistake coming back to our home component or not home sorry the add comment what's happening here I'm posting only after post I'm mutating the data and that's wrong we want to mutate before we post right we mutate we post so when we post and we mutate before we immediately change the data that our users are seeing then when the post is finished and it comes back it just updates if he has to update the data from the table right so let's just try this way and I think even before going to the browser I still have another bug there okay but yeah keep with me let's try again so let's say JJ JJ comment you see JJ immediately okay but then JJ disappears why is this happening okay okay do you remember that I said that I didn't want to pass the revalidate to false actually probably I need to pass the river today to false and why why that because when I'm passing this revalidate to false I'm not reapply ting that okay I'm just mutating the state I don't want SWR to do another call to my server okay I just want to mutate the state and then after my call is performing these okay then yes I need to trigger okay and I can trigger this bit okay so now I want to go to the server trigger another call in the server and when the server responds or replies I just applied my cache okay another import over there and I'm starting to get an ID of having all of those strings we will go back to it as I said before okay so if we come here and we refresh let's just call it why why why why why good enough so adding a comment the why why why sooner or later will now do the call and okay now you have the seven okay some API is okay will also return to you immediately the next state in the post if your API does that then you can just do another mutate and passing again the revalidate to false revalidate is only saying that it will do another call to your server okay that's what revalidate so depending on your API you can do that or not my mock server it just returns the current one that we changed or that we added okay so coming back here as I said the next step is to delete okay and the delete will be really really similar to what we did with the head okay so let's start the delete let's go to our home okay and let's just put it there and let's go to our home to do and where do we have the button to delete it's here okay so let's come here and let's do one click okay so now when we click this function will be invoked and what do we want to do in here we want to do a access delete of that endpoint and on top of that we want to pass the ID and so the ID is Rho dot ID so we can do something like this excuse dot post I don't know why axis again capitalized vs code so oops not there so we need to do HTTP slash slash local lost 4 0 0 1 / comment / Rho dot ID okay and this is not a post I said that I wanted to do a delete right so let's just do it simple first and then we can start to play with mutate and trigger again okay but let's start by the simple version let's come here and see oops didn't win port axis already oh no we didn't we had it imported here but then we removed off that's why vs code was changing axis to capitalized a vs code for some reason prefers it that way I don't so now saving going back to our browser let's just refresh to make sure that everything is up-to-date ok and after it it updates we can just come to the first one and click do it and hopefully it's bending it responded okay so hopefully if we refer everything should be without the number one now right yes now the first one is number two so let's do what we did for the add comment in the delete so the first thing we want to do is to remove that one immediately okay and then we want to trigger so let's do mutate of design pointer and yes I'm starting to get really annoyed with myself so let's just do this so let's do URL over there and at least I will not be dead annoyed with myself so we will have mutated then we can do data and dot filter and we will filter by what by the idea because we have the robot ID so we can filter element or comment and when the comment that ID equals equals equals to Rho that ID actually is the opposite filter we want otherwise we will delete everything except that one right so we want to delete all the others except that one so let's just import this if we ask this with us yes it is so we immediately trigger that change and then the next thing is to say false we don't want to to trigger immediately but we want to trigger after this one so we can do this you are hell and why is this muted complaining to us cannot find the name you tight oh really but it's there how can't you find it okay import okay let's go down I am now it's trigger is just yes code my computer is super slow it already crashed once okay so if we refresh this page okay and we wait the two seconds and now I'm starting to regret my my decision to make the mock server take two seconds but we can come here and oops it failed miserably because I'm stupid now the URL we want is still this one okay the only one we want with Rho dot ID is the one that we are doing the delete verb okay all the others so let's call this delete URL the URL and let's call the other URL equals to just this bit okay okay so now we can do these and these and now yes it will work okay if you didn't understand what happened literally I was mutating the URL with slash ID in this case it was two okay and what I should mutate is the top-level comments URL not the slash ID okay so now I change mutate and trigger to have those as the defined ones so if we come here we refresh now we don't have to because we already deleted it in the previous reload of the page but we can come here delete for for example for immediately disappears we triggered now to get the comments and when it finished for is not there so our page is perfectly its pristine there okay and if you start to do this a lot your application will look much more responsive to your users and let's be honest the amount of work you have to do with with something like SWR is not that much and even this one is kind of optional right or in reality the trigger is optional so you probably don't even need to trigger some of the times if it's a page that only your user cares about you probably don't even need the trigger you need the trigger most of the times when you have something like this let me show you you open this page you open oh this page was really old so you open this page and this page and in one of them you say hello world for example right and we save and now this page as hello world okay and we come here and we do a delete of number three okay but imagine that when we did the delete of number three we also deleted something here so the page just can be not synchronized even though SWR will synchronize when you move to that tab but if it was a real different user not in the same machine but in two different machines you want to just reget the latest state from your server so I would say usually is a good practice for you to have the trigger still but it's up to you and the requirements of your application right if the user is changing is own profile picture probably don't need to trigger again because he is the only person changing is own profile picture so we did almost everything the last thing I want to show you is how to make that base URL because at the moment as I said as you can see we are passing this localhost 4001 all over the place right so let's go here for our app that TSX and if you are in a create react app this is the normal app dot GS or adapt to update JSX or something like that okay so we have access over there already yep so we can do excuse default and we have something called base URL equals to HTTP local host four zero zero one okay and I don't want the slash because I want to put the slash everywhere else and so with this you can even have an environment variable for example while you are compiling the application you can have an environment variable my endpoint okay so if you haven't point you use that one if you don't have any point you use your mock server you can have something like that okay and it will just work it's completely fine for now I will just keep the down-low Kalos like that and this is one of the reasons I really love axis the other one is interceptors even though we will not touch interceptors today but if you ever used an interceptor in axis you know the power it can give you for example if you are doing an HTTP call okay and you want to authenticate your user against average typical and add some and to your request with an interceptor you just do it in one place you don't need to populate everywhere that ever one place and it just works okay so this is this was one of the last things I wanted to do to you today but just to prove it works we can come to our own dot the X X and we can delete these from everywhere okay so let's just do these okay and now we will also remove in the wrong place but let's move on I know actually not because I have the slash okay so I removed everywhere blindly but let's see if the application works okay let's just close all of the files to make sure that everything was saved refresh and if it works we have a nice tutorial for today right everything seems to work let's just say hello once again hello Bruno okay yep it seems to be working it will take now two more seconds and we have that thing over there we can delete it will do another cost two comments when this call finishes no update so everything looks super fine you can go to the next page you can come back and you still have everything cached really great user experience right so if and that's the only reason I did this tutorial in next jeaious is if you have an application and this application is using next Jas you can have an initial values here in in SWR so let's say that you want to pass initial data not initial values initial data so we can say that by default we will have a comment called Bruno for example with ID 1999 for example that number okay and that can be quite powerful imagine that you are doing server-side rendering okay you did your server-side rendering you already did your fetch call over there so when your component we hydrate in in the client browser you immediately inject that initial data so the user will never see any flickering or anything weird happening right so if we come here and refresh you will see that by default my application will start with 999 brillo and when the call is finished then it just puts whatever new value and in an XJS you can oops I wanted to go to my browser okay you can come to next J s okay and in the next yes oops github okay you have something to load data okay and that thing is get initial probes oops they don't even have it here okay so let's see if they have it in the documentation next J is next website next is so Doc's and let's see if they have get initial initial what is that get ice initial probes okay my bad so we can have something like this okay so let's do this okay we come here to the bottom okay and here at the bottom we can have our axis like we already have and our axis because we already have to advise URL so we can just do comments okay and we will get that rest in the rest we will put in data okay and so we don't need a wait for our data so we have our JSON okay so we can say these and we can say what you want to call it comments from summer is it a good name probably it is okay so we can come here and say that we receive comments from server and we can even say any for now okay just to not worry too much about it so we can have this and this will immediately do server-side rendering for you with the HTTP call okay so when your application on your browser let's go to our application okay oops oh okay it's not a page we called it oh okay close enough so we called it out right so when we have that and is still reloading so hopefully when we refresh and you will see that immediately our application is loading with that data so if you come here and you put all okay and you come to the localhost okay let me just open this and you do preview this is the first load and your page is immediately there with all the data that you will ever need okay and the application is still working okay the application is not broken hello Bruno's and add comment and the application is still working as you would expect this application to work so I really really hope you like this tutorial and next week we will come back for more so please if you really like this like the video and subscribe see you next week bye bye
Info
Channel: Bruno Antunes
Views: 59,847
Rating: undefined out of 5
Keywords: javascript, react, swr, react hooks, hooks, typescript, cache, http, axios, cache requests, cache http, next.js, React, ReactJS, Reactjs, ReactJS Tutorial, React Hooks, React Hooks Tutorial, ReactJS Hooks, ReactJS Tutorial for Beginners, useEffect Hook, Fetching data with useEffect, useEffect Hook in ReactJS, http cache, axios cache, react cache calls, react cache http calls, cache xhr, cache get calls react, swr cache, swr for begginers, javascript for beginners, http for beginners
Id: a7JigiLw_OY
Channel Id: undefined
Length: 36min 45sec (2205 seconds)
Published: Mon Feb 10 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.