My Favorite Way to Fetch Data in React

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
at the moment I'm spending a lot of time on an app that is next.js in the front end and Express in the back end and the big requirement for this application was I need a data fetching Solution that's super robust it needs to have amazing error handling I need to customize caching and it should just have a lot of utilities built in and the solution I went with is react query now a lot of people have asked me in the past Josh why not use use SWR from versl and I think they try to accomplish the same thing and react query as a very robust data fetching solution has worked super well for me and that is super important because in this app you can create articles it has a full stripe integration and these articles are being streamed to the client in real time and there are a lot of data fetching implications that come with that so let me show you how you can Implement a robust data fetching solution into your own react applications as well to get started we're gonna go into any react application I'm using vid for this and let's take a look at the data source that we want to fetch from this is going to be your API in Express or your next JS API route or Ruby back and python backend does not matter and let's quickly take a look at the data that comes back when we fetch this URL can do that with curl that's a hundred block or little posts I guess that came back from this URL and if we have a number after the slash we just get oops we just get one back just one post this is the data source I'm gonna use in this video to fetch from you would use your data source now to get started with react query it is pretty straightforward do not be intimidated by it really it's very simple let's quickly stop the development server and now let's install npm install or yarn add I'm gonna use yarn and that's gonna be at 10 stack slash react Dash query this is the dependency we need to install it's finished installing okay this is me editing Josh and I felt like I explained it pretty horribly in the initial video and so what we need to do before we can get started fetching across our application is provide the whole app with a context we can do that in the main the root react file by saying query client provider this query client provider takes something called a client and this client is what we're gonna call a query client it's not super important you don't need to understand exactly what this does because it is just a context after all and the query client is something that we can declare up here a query client that is going to come from 10 stack react query as well as a new instantiation of the query client class that we can import invoke and then make accessible throughout the whole application by wrapping or app in this context provider that react query requires and now we are all done and ready to get fetching across our entire application we can close all of the main file and now we can actually fetch or pause and display them to the user and the way we're going to do that is with something called a use Query but we are not going to use a query for everything in react query there's two things we're differentiating between a use Query and a user mutation here on the right hand side a use Query is made for get requests and the use mutation is pretty much for everything else I guess you could also use the query for delete because you're not passing a body content and that but if you wanted to do something like a post request something like a patch request that would all go under the use mutation use Query is for getting data use mutation is for mutating for changing data that's why that's where the name is coming from so first off let's try just fetching information to get started and to do that let's go into our file where we want to fetch the data and say const an empty object because we're going to worry about the structuring later and this is going to be equal to use Query and import that we get from 10 stack slash react query now this query takes something interesting that is called a query function and if you fetch data the regular way Collins Post is going to be equal to a weight fetch first off you need to do this inside of a use effect to actually be able to await the fetch in the first place and then secondly the function we don't need to await that anywhere we can work with it kind of synchronously in in Big quotes because it's not really but we don't need to worry about the await at the top level anymore that is one main benefit of react query so we can define a function and this function is going to run every time we want to fetch data and here goes the regular fetch however I prefer axios so let's quickly add axials axials is an HTTP client you can use instead of Fetch with a bit cleaner syntax and instead of you know fetching the data like this with a fetch inside of here I'm gonna say cons data is going to be equal to a weight and now we can use a weight we're not at the top top level anymore we declared the query functions asynchronous so we can actually use the await now import axios dot get because this is a query right here we're going to make a get request inside of you and then here goes the URL I've already already prepared that let's just fetch the post with the hard-coded number of one for now and then very important after fetching the data we also want to return it from this function now this is not typed because react query has no way to know what this type is we do however right we looked right here let's declare an interface this only goes for typescript by the way if you're in JavaScript do not worry about this particular step it's very simple let's just call it data um and put the Json string we got back in here remove all the quotes to turn it into a JavaScript object and remove the double object notation and now the user ID is going to be of type number the ID is going to be of type number and these two are going to be of type string and if you're in typescript you could just copy that interface and cast the data into that type by saying as data and now when we destructure that's why I put an empty object in the first place when we destructure whatever we get from react query for example the data that we get back from the query we can see this is of type data or undefined undefined the reason it is is because it needs some time to fetch right it's not there immediately when the component renders so first it's going to be undefined and then the data is going to be put in there once the query function has run successfully and let's quickly test that out let's render out the data down here in our component and we can see I think this is um okay now this is just a single object okay that works so let's just render out the entire data by saying json.stringify data just put it all in there go to our development server and see what happens it's going to make the request and that obviously only works when the server started let's go back refetch and we can see the data is there immediately okay now that's not a huge advantage over the regular fetch API as it is because after all we're not making use of most stuff that react query gives us for example we could also have an is loading and let's just mock a loading state so you can see the full beauty of this I'm going to declare a little constant here called weight and that is going to be to mock a query delay let's await a weight of 2000 so we get a longer loading state so I can really show you what this does so if we are loading that is a property we can destructure from use Query from react query this is not something we need to keep in mind ourselves and this state is being tracked for us depending on the state of the function that you pass in that is a major benefit we can say if it's loading then we want to render out content is loading and else we want to render out the entire data string now see what happens it's going to take a little bit once I load content is loading it's going to wait two seconds because we awaited that and then it's going to show us the entire data do you realize how cool that is how much cleaner the syntaxes we do not need to worry about anything else and same goes for something like is error and we get a bunch more methods in here we get something called a refetch if we wanted to refresh the data and I think by default the data is refreshed every time we revisit the page so it's never stale if I just switch back between tabs the data is refreshed now one property you will see passed very often into these queries is something like a query something called a query key and this query key is a string array and the reason this exists is for caching now these are hashed deterministically which means if we pass some values as the second parameter for example I'm just going to declare a my VAR as an empty string and pass it in here if we had multiple my vars we wanted to pass as the query key all of them together making up the query key the order of these would not matter we could pass my var2 myvar you know just zero without anything or in this order and it would not matter it would be the same core Ricky and that is relevant for caching because caching is based on a query key and before showing you one really cool trick how to make this code way cleaner even more so than it currently is let me show you how to use a mutation for making a post request because it is really straightforward and I think the sun is making my face look really bright anyways instead of the use Query we're going to use a user mutation and if we wanted to Cache that we could use a mutation key I'm going to Omit that for now we don't need that and now instead of a query function you're going to need a mutation function I'm gonna get rid of the wipe and because this is a mutation remember mutation is used for mutating or changing data instead of making a get request we could make an axial's post request in here and as the data we could pass um you know my Val just a just a string you know that's going to be what we are going to pass in the post request body to this endpoint now I don't think this endpoint takes a post request but it would work the same way and then we get access to whatever we get back in the data so mutation is meant for post patch or changing data in general and a query is meant for getting data okay however we can do something way cooler than this let's get rid of the weight function and let's abstract this into its own hook we can do that by creating a folder called Hooks and let's call this use Dash pause oops post dot TS now what we can do in inside of this Hook is very beautiful let's export a const called use post it's going to be an arrow function and this Arrow function takes a post ID of type number we know this needs to be of type number because this this ID is expected by our endpoint as the post ID that you can see right here it's just a regular number and not a string that's how I know this is going to be of type number and then let's paste or query function let's change this back to a query function in here and similarly we need the query FN inside of here and we also need to import that from react query in order to work we also need axios and let's Port over the data type because instead of declaring this everywhere where we are using this function let's declare it centrally wherever we Define the function which is way handier as a first step you could try something like return data and is is loading from this hook that would work just fine there is a better way but let's leave it like that for now then we're gonna make a get request and also a get request means we cannot pass something as the body and instead of hard coding this is URL let's dynamically insert the post ID in the form of a JavaScript template string that we get passed into the use post we can save that and now switch back to our main components so wherever we want to get the pause let's say cons pause is going to be equal to use post and we can pass it a post ID for example we want the first post normally this would be a dynamic value but I'm going to hard code it for now and let's destructure some properties we know we can do that with data and the is loading we know we can destructure those because we are returning them from the hook right down here that's why we can destructure them however we can't get access to any other query properties except if we desstructured them here and then inserted them down here which is honestly totally unnecessary now just very quickly to recap this is already way more beautiful than it was previously I mean look at the syntax it is beautiful we can make it even better though with one very slight adjustment instead of returning these properties that we destructure how about we return the use Query itself because that is returning all the properties that we can destructure right so we can just return the use Query and if we save that and take a look at the data that we can destructure from the hook now it's everything that the use Query normally has is stale is refetching its previous data and so on now you can benefit from all of the use Query features right where you call this endpoint or rather where you call the hook the hook calls the end point and you call the hook if we save that and take a look at if it's working we can reload the page and see that it's not working because I left a small typo in here now let's refresh and we can see it is working great and if it wasn't working if we had a typo in here like jsonairplaceholder.com how would we deal with that now the second big argument for react query is the graceful ways in which you can handle success and error States we can do that as the second it's not really an argument we can pass it just into this big option object that we have in the use Query we can pass something like use success and also get the data that we fetch right past into this callback which is beautiful because now we can handle the success State accordingly do we want to refresh the page do we want to you know you can do anything in here and same goes for something like V on error we get access to the error right here we can post a toast notification to the user and so they know what happened in the error and we have a couple of other options that help us keep track of caching for example there is the cache time you could use super important and a lot of other stuff how often do you want to refetch do you want to refetch when the user reconnects on the window Focus right do you do you want that do you don't want that a lot of options that you can play around with that would go Way Beyond the scope of this video and but they are there and they allow you to really perfect react query to whatever needs you have in your application I'm wishing you a lot of fun implementing react query with all good things that come with it into your own react applications chances are if you're wondering how to implement data fetching properly in react you might as well like this video that's showing up on the top somewhere right now regarding a super cool GitHub repository I learned so much from if you want to write better react code chances are you also like that video alright that's it for me for today I'll see in the next one I have a good one and bye bye
Info
Channel: Josh tried coding
Views: 54,534
Rating: undefined out of 5
Keywords: react query, tanstack query, react query tutorial, react query typescript, react query mutations, react query usemutation, react query nextjs, react query axios, josh tried coding, joshtriedcoding, react data fetching, react fetching data from api, react data fetching best pracices
Id: PmPkAAu_QF4
Channel Id: undefined
Length: 16min 28sec (988 seconds)
Published: Wed Apr 26 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.