Use Axios with React Hooks for Async-Await Requests

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
custom hooks allow us to add reusable functionality to our react apps in this tutorial we're going to create two different custom hooks with axios you can see in our example application that i've got a component that gets a random dad joke and we can get a new joke if we want to and that uses one of the use axios hooks our second component uses a different use axios hook it fetches user posts and we can submit a new post and get the response we can also refetch the user posts let's see how both of these work in react and which use axios hook you like best [Music] hello and welcome hi i'm dave today we're going to create two custom use axios hooks that you should be able to reuse in future projects too i'll share links to all resources and source code in the description let's get started okay i've got visual studio code open and i've got our react project open to the package.json file what i want to emphasize here is that you need to install axios i have the latest version as of the making of this tutorial maybe you're watching it at a later time and there's a new version open your terminal window with control and the back tick or you can go to the terminal menu in visual studio code and choose a new window either way type npm i and then axios and press enter to install axios into your project i already have it installed so i'm not going to do that but i just wanted to emphasize you do need axios for this project okay i now have the basic app running in chrome here on the right and visual studio code on the left we can see our app.js with our app component it just has an h1 heading that says axios hooks and we want to create our first axios hook i'm going to do that in the source directory i'm going to create a new directory called hooks and then inside the hooks directory i'm going to create a new file called use axios.js now i'm going to press ctrl b to hide the file tree and i'm also going to expand visual studio code so we have lots of room to see our code i'm going to start by importing use state from react and i'll also need use effect for this hook after that let's define our use axios hook as a function not with zero there though and now inside the function we're going to have a request or i should say a config object and so we'll say const and then we can pull in everything we need from this config object which will actually be passed in up here config object and we'll be destructuring it here with our const and so the first thing we'll have is an axios instance and this will allow us to use this hook with more than one instance of axios then we'll also have a method and a url and then we'll have a request config object and we'll set that with the default value of an empty object now i'll save and briefly let's talk about this i'll resize visual studio code and in chrome i'm at the axios website and looking at their docs and really the request config object is just one big object when we're pulling a couple of those out specifically the url and the method that we will absolutely need now the axios instance is not part of this config for axios however everything else is and the rest we're just going to create an object called request config it will have the headers the data anything else we want to pass in will be inside of this object and i'll put a link to this in the description you can see all of the different settings you can pass into axios and that's what this will hold okay back to visual studio code after we've destructured our config object we need to set up our state so we'll have a response and set response and i'm going to set this equal to whoa on the wrong line there we go set this equal to use state and this will be an empty array after that i'm going to press shift alt and the down arrow and get three well two more lines let's use two to start out with have response and i'll set select the next response and change that to error error will be an empty string to start out and then i'll select the next two response words and change this to loading and loading is going to be either true or false a boolean and we'll start out with a true value now looking ahead we're going to want to return all of these values at the end of the hook essentially so here let's return the response and then the error and the loading values that we have now we're going to put the bulk of this hook inside of use effect so let's start with our use effect and this use effect should only run when the component mounts so we'll just have an empty dependency array to start out and i'm going to scroll up to give us more room because we have a lot to put in here the first thing we're going to do is create a controller and we're going to set this equal to a new abort controller that will let us cancel the request if we need to and that will prevent a memory leak now what you may have seen others or myself do in the past is create a let is mounted up here a variable called is mounted and set it to true to start out and then we're using the let keyword so we could change that value but really we don't need this pattern when we use the controller and this is mounted pattern really just kind of puts the warning to the side rather than solving the problem because if you see that it's already an issue and i'll put a link to an article that describes this in more detail in the description however just know that we really just need this controller to abort the request and then we won't have a memory leak now i'm going to define a function called fetch data and this will be an async function and inside this function we're going to have a try and then a catch and the catch of course gets the error and then after the catch we'll also have a finally block so inside the try is where we will make our request so let's define response here with just an res since we already have a response state i don't want to name them the same thing it could get confusing so we have await and now we'll call the axios instance that we have received and now we're going to say what method it is a get a post a put so on and axios expects this to be lower case here although methods are usually referred to an upper case so what i want to do is put a two lower case attached to this method because it would be easy to pass it in as uppercase and now we want to have the url value and now let's come down on another line and we should have an object actually i want to start the object above so i'll put the opening curly brace there and the closing curly braces on the bottom line and here we'll spread in that request config object and then we need another line because we're going to pass in the controller dot signal and that is that abort controller that we defined up here so this attaches the signal to the request so we can cancel it if we need to now just because this is a tutorial i'm going to go ahead and log the response that we would get if you want to see that but we'll also want to set the response and it would be response dot data is what we really want to set in the state now in the error block we'll go ahead and log the error as well it's error.message and then we need to set the error and that would be the same to error.message and then in the finally block finally runs whether we have an error or whether the try was successful either way finally is going to run so we just want to set loading equal to false at this point so we're not endlessly in a loading state and now we've defined our function that starts right up here fetch data but we haven't called it yet so i'm going to just select the name come down underneath the definition and we'll call the function into action here and now we also need to use the use effect cleanup function and that's what this is right at the end of use effect you don't always see it but it will come in handy here and we'll just have an anonymous function and we're going to call the controller dot abort because if the component unmounts this is what would run and that's why we would want to cancel that request so we don't have a memory leak and now if we scroll down we should be able to see no we don't have our export yet so let's go ahead and say export default use axios here at the bottom and save now we need to create an axios instance so let's go back to the file tree and in the source directory let's create another new directory and call it apis inside this api directory apis actually let's create a new file and i'm going to call this dad jokes.js and this is where we're going to create an axios instance now i'm just going to paste this in it's not too much here and we'll quickly go over it here is where we actually import axios from axios right here at the top then we create a base url value and put in the url of the api maybe not the specific endpoint but the root url or the base url if you will then we say export default axios dot create and we create an axios instance here and we set the base url value and it's the same as the constant we defined above and then we can set anything else that we want to that's specific to this api right here however these values could be overwritten with something we add to that request config object inside of the hook but this is what this api needs we specifically want to say we accept application json this api would return html if we said text slash html and so on so this is what we want in this instance i'll go ahead and save this file and now we need to create a components directory and so i'll also add that inside the source directory and inside the components directory let's create a new file and call this jokes dot js now i have an es7 react snippets extension installed which allows me to type underscore r a f c e and i will press enter and it helps me start my functional component because now i have a jokes functional component already has the export statement as well so i'm just going to come up here and go right above this definition and start my import and i want to import the use axios hook that we created and then i also want to import axios but it's not going to come from axios it's going to come from that apis directory and inside the api's directory we have the dad jokes instance that we created now let's use our hook inside our functional component so at the top of the hook i'm going to say const and now we'll bring in a joke the error loading and then we'll set all of that equal to use axios and then we'll have the values that we pass in to use axios and the first is the axios instance and we'll set this equal to the axios that we have imported into this component and then we'll set the method and here we can now use caps as you typically see the methods referred to get post put delete and so on and then we'll say url again lowercase and this will just be the root it doesn't have a different endpoint for this particular api then we're going to have our request config object now we could just ignore this if we didn't need it because it defaults to an empty object already but let's go ahead and add something in here just to show we can do it so we're going to add headers now we already had headers defined but we can add more headers here specifically with our request and i'm going to set the content dash language and set this to en-us and it's worth noting that we could overwrite like if we wanted to receive html here we could overwrite the accept header and add in that text slash html if we wanted to i don't want to do that right now i still want to get json as we had previously said it this would also be the place then to put other things that come from the request config that's documented with axios so we could have data here if we were sending a post request for example and be sending along the data with this request so i'll delete this for now because all we really want is this much okay now let's scroll up and put in our jsx i'm going to change these divs to an article element it's more semantic and i like to use semantic elements when possible the first thing i want now is an h2 and i'm going to put random dad joke okay after the h2 i'm going to press ctrl b to hide the file tree again so we have lots of room here and i'm going to check the loading state that we received from the hook and if loading is true then i'm going to go ahead and just put a loading message here inside of a paragraph after that let's go ahead and check the loading state again but we want it to be false and if an error is true then we're going to send a different message and i'll once again put a paragraph i'll give it a class name though because i want to style the error message differently if we have one and now after that i'll just put the error in here that would be the error state and display that after that let's go ahead and check the loading state again to make sure it's false and make sure the error state is false and then we will check to see if we have a joke and then if we do have a joke we'll display that joke so we'll put that inside of a paragraph and we'll get our joke state and then it would be a joke property that holds the joke as well and finally i think i'll just copy this down and we'll use this next line because we're checking to see if loading is false if error is false and now also if we don't have a joke state so if none of those exist then we need to put out a different message and we'll just say something like no jokes to or no dad joke let's be specific no dad joke to display now this might be more readable if we were to break it apart for different lines like this but overall we get the idea and it's just kind of a falling order of logic here of what is going to be displayed inside of the jsx now let's go back to the file tree and choose our app.js so we can import our jokes component and then hopefully we can see a joke in our application so we're going to import jokes and now that we have that component imported let's go ahead and use it inside of our application so here we should have jokes and save now let's resize visual studio code and take a look and yes we have a random dad joke what do you call a boomerang that won't come back a stick definitely a dad joke okay so the only way we can get a new dad joke right now is to refresh the entire application so we do get a new joke that way but it would be nice to have a button that said get joke and we could just request a new joke without refreshing the application so let's add that functionality okay we'll go back to visual studio code and choose the use axios hook file i'll expand visual studio code and we need to scroll up we're going to add just a little more state to this application so let's say const and now i'm going to call this state reload and set reload and we'll set this equal to use state and it'll just hold a value of 0 which will work for us after that let's go ahead and come down a couple of lines we're going to define a new function and i'll call this function refetch and then let's set this equal to an anonymous function and use the set reload and we'll just pass in the previous state and then we'll say previous plus one for the return and save so the concept here is we're just updating the state in some way that will cause once again the use effect to run and then it will make the request for us so all i'm doing is adding one to the current state you could use a boolean probably to switch between or toggle between true and false as well either way that should work but to get it to work we're going to need to put that reload state inside of the use effect dependency array so we'll put reload here and then you'll start getting a message since it's not just an empty array that you don't have in all of the dependencies but we know we only want this to run when the component mounts and then if reload changes so i'm going to paste in a comment that will disable those warnings the es lent dash disable dash next dash line however you don't want to abuse this you usually want to listen to the linter that is telling you those things it's just that we were only using this when the component loaded and now we only want to use it to re-trigger the use effect again so that's why i'm using this right here and then finally what we need to do is return that function so we can call it inside of our component so we'll also pass the refetch function into the return here with the response error and loading and now let's save the use axios hook once again we can go back to our jokes component now and we should be able to pull in this function that we just added so here is refetch being pulled in as well as the joke error and loading states and now we can use that maybe in a button down here inside of our jsx so i'm going to add a line and then create a button and we'll say git joke should be the text on this button let me add an extra line here just because we had spaces between all of those then we'll put in an on click and inside of our on click we'll have an anonymous function and inside of the anonymous function we'll call our refetch function that we have now received from our hook let's go ahead and resize visual studio code again and check it out now we have a get joke button and we have a current joke so now let's press the button and yep we got a new joke and we can keep requesting jokes now with our button because we're using that refetch function that we created and it simply triggers a re-render because it updates the state okay back to visual studio code and once again let's look at this use axios hook that we've created this is a good hook overall it will request the data for us and we can re-request data as well however sometimes you might want more flexibility maybe you want to post data put data delete data all of those crud operations and you want to be able to call it within other functions and the only way we can do that is to return a function like we did with our refetch function here so now let's create a use axios hook that actually returns a function and that will allow us to call it and also use it for all crud operations where we need it to do this i'm going to click inside of our first hook press control a to highlight everything and control c to select it all so i don't have to recreate everything we'll just modify this hook into the other hook that we need so now inside the hooks directory i'll create a new file and call this use axios function.js and inside of use axios function we are ready to paste in everything we had from the first hook and now we'll be able to modify it i'm going to press ctrl b once again to hide the file tree at the top the imports of use state and use effect are still the ones we need we're going to change this use axios function so i'll select it and press ctrl d to get the other use axios as well and go to the end and just add the word function onto both okay now i need to scroll back up to the top and we'll work our way down use axios function will not receive the config object actually the function that it returns will receive a config object so we'll be able to use this later i'll just go ahead and press control x and we'll need it soon enough to paste it back in now i'll go ahead and remove these spaces here and we have our state response error loading but the reload state won't be reload anymore we're going to select both reloads and change this to controller so we'll have a controller and set controller state and it won't have a zero it will just be empty also we should note let's set the loading state to false because we might not immediately be requesting data with this hook maybe we would just be using the hook to post data in a component so we'll switch this to false to start out now we can delete this refetch function altogether and we can start our function that we're going to return let's call this axios fetch here and this will be equal to an async function and it will receive a config object as we previously had and now inside this function is where i can paste that config object that was destructured that we currently had before i just cut it and now i'm pasting it back in now let's scroll down and grab the try catch finally block out of the fetch data function that we had in the previous hook and i'm going to paste it up here we will make very few changes to it but there will be a couple so the first thing we'll do inside of the try block is set the loading to true because remember we now started out as false after that we're also going to define a controller i'll just call it control with the standard abbreviation so we know what it is and this will be our new abort controller right here after defining that i want to call set controller and then pass in the controller that we just created so now we're storing this abort controller in state after that we also need to change controller to our abbreviation for controller here so it still is able to call the signal on the request if we want to cancel it after that everything in the rest of the try block the set response and then the catch block and the finally block all remain the same let's scroll up and look at our use effect because it will definitely be different we can delete everything we see right here and we will pass in the controller state so let's go ahead and put the controller state in here as a dependency will no longer need this comment because we shouldn't get any annoying warnings there for the use effect dependency array because we are passing in what we need here as the controller and just because this is a tutorial we could go ahead and log that controller to make sure we're getting it if we want to inside of use effect now the only other change to make is to remove refetch from the return but we need to include axios fetch that we created and we can save and now we've modified our hook into a function axios fetch that can be called inside of our component wherever we need it so let's go ahead and apply this to another component but first i want to create another axios instance let's go back to the file tree and back to our apis directory it will create a new file and i'm going to call this json and then a capital ph for placeholder the json placeholder site is what we're going to use i'll paste this in once again and we can quickly discuss once again axios from axios here and then we set our base url and everything else is pretty much like we saw before we're just creating a new instance with the new base url and we're setting a specific header notice i'm not even setting an accept header here just the content type now i'm going to save that and go to the components directory and create a new file inside of the components directory called posts.js let's start inside our post component by importing what we need and we'll import axios and this is going to come from not axios again but our apis folder and then inside the apis directory we should have our jsonph instance of axios and that's what we need here then we also want to import use axios function that we created that hook and then we're going to need use effect so let's go ahead and get that also and now with our imports complete we can go ahead and define our component i'm going to use once again underscore r a f c e which uses es7 react snippets extension press tab and there is our components outlined fairly quickly at the top of the component we can call our hook so we'll say const and now we'll pull in posts we'll also pull in the error and the loading state and the function that we need axios fetch and this is all going to be equal to use axios function and we don't need to pass anything in here now let's define a get data function that's actually going to use our axios fetch function that was returned so inside of git data we'll call axios fetch and then axios fetch has an object that configs it so we'll set this to axios instance and that's going to be the axios that we imported the specific instance we'll have a method here and we can set this to get and then let's also set the url and we're going to look at the posts url here and we can save okay after that let's go ahead and add a use effect where we can request some data when this component loads so here's use effect and then use effect will have an empty dependency array that we'll add right here and then inside of use effect we're going to call git data now it will complain about not having get data inside the dependency array so we could once again put in that comment if we want to that says don't give us the warning about the dependencies we only want this to run when the component loads and finally just to show we can use it for another purpose let's go ahead and create a handle submit function so i'll say handle submit i'll set this equal to a function and we need to put a cost in front of handle submit there we go now that we have started handle submit we'll call axios fetch inside of it as well and we once again have a config object i'm going to copy these three from our fetch we'll just change what needs to be changed here so we'll still have the same axios instance this will be a post method and it will still go to the same endpoint i'm going to scroll up a little bit because now we can add our request config object here as well so we'll say request config and this will be an object and it's going to have data that would be posted now you might actually tie this data to a controlled input or two in a form or something i'm just going to send static data just to show that it can be done and of course you could modify this to your own needs so here i'll have user id 10 and i'll set the title equal to axios stuff and then i'll set the body equal to axios hook stuff okay now it is time to go ahead and update our jsx once again we'll switch these divs to articles and then i'm just going to paste in what we had from our dad joke component and we will modify it i'm going to press ctrl b to hide the file tree because we can quickly add that logic that way okay the first thing we want to do is just put posts up here in our h2 after that our loading line will still be the same and then our error line would also still be the same however the data will be different so now let's go ahead and look at this third line we still want to check it make sure there is no loading status and there's no error but for joke let's switch this to posts and we'll use optional chaining to check the length as well the ampersand is okay but we will come down to another line and we'll definitely won't have a joke here we're going to have an unordered list oh i've got something else to delete there we go now up here in our unordered list we'll have a ul and then of course that will allow us to create a map over the posts here so we'll have posts dot map and now for each post essentially and then we'll also use the index because we need to set a key on each list item so here we'll have the list item i'll set the key equal to the index and then after the key we'll put in some values from the post so i want to set a template literal here and this should start out with the post id post dot id and then i'm going to put a period just the period after the number of the id then we'll go ahead and put post dot title as well and save that much i'm going to scroll for a little more room and that will map over the posts but when we submit we get data back in a different format so i'm going to select all of this press shift alt and the down arrow and now i have another line here that i can just modify so now we'll be checking to see if we do not have loading do not have an error do not have post link and we do have posts data and now i'm going to just select what we had here for the unordered list remove that and paste in what we are going to have here so this will be a paragraph and i need to press alt z to get this to wrap it's just a little long and we're getting some squigglies here that say i have an error because i didn't put the double ampersands after the post data but now we should be good and we're going to take that data that was submitted and we get it back in the response so we'll just display that here inside this response and then finally if there's no loading no error and no posts whatsoever so we don't have post link or post data no posts at all then we want to display no posts to display and we'll go ahead and save and we should be finished with the component except i don't believe we put in the buttons that we need so let's go ahead and add those buttons as well i want to div up here and i'll put a class name equal to row and then inside the div we're going to have two buttons so i'll create the first one our button and it will say submit and then we'll have an on click inside this submit and inside the on click we'll call handle submit okay now i'm just going to press shift alt the down arrow to copy this button down and we'll change the text here this is going to be refetch and inside of this we'll just call our get data function that we defined okay now with the component deftly complete we need to go ahead and add it to our app.js so i'm going to scroll down select app.js and now we can import posts and then we can use the posts component here actually i think i'll just replace the jokes component although we could have them on both i just want to focus right now on the posts so we'll comment out the jokes save let's resize and look at our application clearly a blank page is not what we were going for i'm going to expand chrome open the dev tools with control shift and the letter i and yep there's some error messages let's see what's going on if i scroll to the top uncut type error cannot read properties of undefined reading abort that has something to do with our abort controller when we're calling that so we'll resize once again go back and let's look at our use axios function where we're calling the abort controller inside of the use effect and yes i left something out remember when we defined the state for the abort controller we didn't set it to anything it's just undefined really and so because of that we need to check to see if we have it first we'll say controller double ampersand and then only if we have the controller defined will we call the abort let's save and now let's resize again and hey our application looks a lot better so now we've got all the posts there should be a hundred here so i don't think i want to scroll through all of them but they're all there now let's try to submit that post with the handle submit function and yep we temporarily got the loading status and now we've got the response after we submitted our post and we got all of the information we submitted sent back to us that looks good now let's re-fetch the post with the refetch button yep and we've got all the posts again so it's working as expected i hope both of these versions of use axios have shown you not only how you can get creative and create custom hooks but that hooks don't just have to return values they can also return useful functions and overall there are still many other ways this could be implemented so if you have a favorite hook recipe for use axios or another one please leave it in the comments below and also let me know which one of these hooks you like better remember to keep striving for progress over perfection and a little progress every day will go a very long way please give this video a like if it's helped you and thank you for watching and subscribing you're helping my channel grow have a great day and let's write more code together very soon
Info
Channel: Dave Gray
Views: 42,380
Rating: undefined out of 5
Keywords: use axios with react hooks, use axios in react, use axios in react.js, axios, react, react js, reactjs, axios hooks, useAxios, useAxios hook, axios functions, axios react, axios react js, axios reactjs, how to use axios in react, axios with react, axios async await, axios useeffect, react axios, react hooks, useAxiosFunction, custom react hooks, react js hooks, reactjs hooks, useaxios react, useaxios hook, react axios hook, async axios, axios crud, axios requests, js, async
Id: NqdqnfzOQFE
Channel Id: undefined
Length: 36min 1sec (2161 seconds)
Published: Fri Feb 25 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.