Transcript for:
Modern Data Fetching Techniques in React

In this video, you're going to learn everything  that there is to know about data fetching   in React, the modern way, which honestly is  really important because as a React developer,   you're going to be fetching data a lot in your  applications. Now, before we get into that,   there's two things that I want to mention. The  first one is that if you didn't know, I also   have a course. It's called Project React, and it  teaches you way more than I teach in this video,   and honestly, all of my other videos. It's  going to show you how to build a real project   with React, a big and complex project, and it's  going to teach you all of the things that you   would need to become a good React developer. You  can find it in the first link in the description.   The second thing is that I also have a newsletter  that's all about React. It's called Import React,   and it's completely free, and it's delivered  to your inbox every single week. You're also   going to be able to find that in the description.  Cool. So now with those things being mentioned,   let's now dive into data fetching in React and  learn how to do it the modern way. All right,   cool. So let's begin. Now, I already have a  video on data fetching on this channel that   I did last year, and this code actually that  you're seeing here is the code from that video,   just slightly modified a little bit. What we're  going to do in this video is we're going to take   the code from that previous video, and we're  going to bring it in the modern day and age,   and I'm going to show you better ways to fetch  data, ways that I would actually recommend   that you do in your projects today. Because as  you're going to see, the code that we have here,   the code that's also in my previous video is  something that I like to call the naive way   of fetching data, and I would not recommend  that you do this in a project today. However,   you need to know and understand how to do this,  because it's very important to know how to get   from this to the actual recommended way to fetch  data. So this is the code that we have, right, we   have a base URL over here, which is basically the  place that we're actually getting our data from.   And then we have a couple of state variables here  that essentially handle everything that we would   need for data fetching, right, we have error, we  have loading, we have posts, which is our actual   data that we're getting from the base URL. And  then we also have a state variable for the page.   And then all of the work happens inside of this  use effect over here. So we have one use effect,   we have this fetch post functions, and it  does everything. It handles the loading state,   it actually calls the fetch request to actually  get the data, it then sets the data in the state,   it also handles the loading state by sending  it here to true and then to false, also handles   errors. And even as a bonus, also has the abort  control over here that handles race conditions.   Now, if you're a React developer, you've probably  already seen code like this, right, the thing   that we all have. And if you're a junior React  developer, you might be tempted to do this in your   application. But I would recommend that you don't  do this. Because although this is functional, and   this is going to work, right, it is going to fetch  the actual data as you expect and set all the   states correctly. This is not the efficient way  of doing things. And here's why the first reason   is that you have to do all of this yourself, you  have to write all of the code yourself, you have   to create and manage your own states for error  and loading and all of that. And then you have to   manage this use effect over here to actually fetch  the data and make sure that you're updating the   states at the correct place at the correct time.  And more importantly, not to forget anything. This   is super easy to introduce bugs, I can guarantee  you that you're going to forget something if you   do this a lot. And you're going to introduce bugs  and you're putting a lot of work on yourself when   you don't actually have to do it. And then another  reason why I wouldn't recommend that you do this   in your project, one that might not be so obvious  is that this is actually missing functionality   that you would typically expect from data fetching  in any application, right? For example, caching,   we have no caching at all here. If we're fetching  the first page of the posts, and then we're going   to change to page one and go back to the first  page, we're going to hit the back end again,   even though we've just fetched the first page  again, and we should have cached that data and   we should have returned the results from the  cache instead of hitting the back end again,   right, that's something that you would want to do  in an application, right? That's a sign of a good   application, you cache your data, and you don't  hit the back end unnecessarily. With this code,   we don't have this. And if we wanted to  implement this, we would have to implement   caching ourselves, which I hope that you know that  it's very difficult. But then even if you were to   implement the cache yourself, you're still missing  functionality, for example, background refetching,   right, let's say that you do have the data in  the cache, and you're showing that to the user,   ideally, what you will want to do is at the  same time, trigger a request in the background,   the user doesn't see that to just refresh the  data in case that there's new data to be found,   right? That's another functionality that if  you want to have, you would have to implement   yourself. And there's so many more things and  doing it this way, you're going to have to   write all of that code yourself, you're going to  introduce a lot of bugs. And if you want to have   this in any other components, or even share the  data in other components, you're not going to be   able to or it's going to be very difficult to  do yourself, especially as a junior, right, so   I wouldn't recommend that you do this in a React  project. However, there's one exception, there's   one time where I would actually strongly recommend  that you do this. And that is if you've never   worked with React before, you're just learning  React. And you've never done data fetching in   React before, I would in that case, have you do  this, because this is going to teach you a lot,   first of all about React and how it works, it's  going to teach you about data fetching and all   the different pieces that you need to know and  think about to actually fetch data successfully.   And it's also going to teach you a lot about  use effect, right, you have to do all of this   using use effect. And you have to learn about the  lifecycle of use effect, which is very important   and seem a crucial as a React developer. So only  in that case, if you're learning React, if you've   never seen this before, I would have you learn  this, understand this, and then you can move on to   doing something better. And this is exactly what  I do in project react in my course. That's why   I push this so much. And that's why I recommend  it because it literally has everything that you   need to be a good React developer. Now, let me  show you the recommended way, the better way,   the improvement way to actually fetch your data in  React, if you're fetching data on the client here,   we're going to go to fetch example number  two. And here we have something very similar,   we have the same base URL fetching data from the  same place as before. But we have a lot less code,   as you can see over here, we still have one state  variable for the page over here, that's fine. But   then we only have this piece of code that actually  has all of the functionality that we had before   in this first example, and even more, but only  with this amount of code. And that is because   over here, we're using React query. So if you  don't know, React query is an asynchronous state   management solution, which happens to fit very  well with the data fetching. And this the benefit   of doing this is that it does all of the work for  you. It does everything that we've done here and   more. And it does it for you. And you don't have  to do it yourself. That's the whole point of using   something. And that's the whole point of not doing  this yourself is because there are solutions out   there that are tested that are well maintained  that do all of this and more for you. So why   wouldn't you use them, right, as you can see here,  we have a data variable, which I alias to post,   this is the same as our post over here, we don't  have to manage it, React query is doing it for us,   then we have is error, right, which is the same as  our error over here, we have a spending and then   we have a bunch more we have is loading, we have  let's see is fetched is fetched after mount is   loading is loading error is paused, you have more  variables in here that you would honestly know   what to do with them. And that's a good thing.  And to get this to work, all that you have to do   is just pass it here a query key, which I'll get  to in just a moment to actually define what query   you're actually fetching. And then you pass it a  query function, which is the same thing that we   had before we're fetching the same URL passing the  same properties. And then you just return data,   whatever data you return in here, react query  is going to put it here in this data property.   And it's automatically going to handle the error  states if this stores an error, for any reason,   it handles it, you're going to get a spending to  know if this is loading or not. And you're going   to be able to use it in the actual JSX in the  same way that you would do it in here. But again,   with a lot less code, and you're not doing this  yourself. And more importantly, this is tested,   and this doesn't have bugs, right. So this makes  a lot of sense. And then you also have other   benefits, for example, the cache, right. In the  first example, you had to implement your own cache   yourself. In this example, with react query, you  don't have to do that by this query key over here,   react query is actually going to identify  what query this is here, we gave it posts.   And we also gave it the page, if we give it  the page here, it's going to know that, hey,   I'm going to have page zero. So I'm going to fetch  the data of page zero. But then if I ever need   to fetch the data of page zero, again, I'm just  going to return the results from the cache instead   of hitting the back end again, which again, is a  performance optimization. And it's something that   you would want in your application, you don't  have to do that yourself, it's automatically   managed. And you can even configure it, you can do  here, for example, stale time, you can configure   how long the cache is actually valid, you can  put any value here, you can put the GC time,   which is how long the garbage collection time is  going to be, you can look at the documentation   of react query to like really understand  these. But you can completely customize this,   and it's all done for you. And you just have  to use this. And you're good to go. And another   benefit that again, is not so obvious, you can  even use the same query in a different component   and get access to the same data, because you're  going to be pulling it from the cache instead   of hitting the back end. With this example, if  I put the same code in a different component,   we would have two requests hitting the same  back end with the same data in two components   that is inefficient, right. So there's a lot of  benefits to using something like react query,   because it does all of the work for you. And you  don't have to do it. And it's such little codes to   actually get this working, right. So if you're  working in a project, and you're fetching data   in a client component right here at the top, let  me remind you, we're in the client environment,   I will get to server at example number three,  in just a moment, I would highly recommend and   this is the standard nowadays to use react query,  or something similar for all of the reasons that   I've just mentioned. And honestly, you don't even  have to specifically use react query, you can use   something that is similar. For example, a lot  of people use SWR, right, it's pretty similar.   It also gives you access to hook over here with  similar data variables that you can also use,   right, this is the same principle. If you're  using, for example, I don't know GraphQL, you're   probably going to use Apollo GraphQL, right, they  also have something like a use query over here,   there you go, you get your GraphQL query, and then  you pass it to use query, which is very similar to   react, right, it's the same hook practically, and  you get access to the same variables over here,   no matter what you're using, if it's GraphQL,  if it's react query, if it's SWR, if it's TRPC,   you want to use something like this that does the  work for you, because the same principle applies,   don't write the code that's already written,  use something that's tested that works. And   that does the work for you. Now, let's move on  to example number three. And this one is a little   bit different, because in here, we're going to be  working within a server environment. So in react,   nowadays, in modern react, you can also do things  on the server, you can have something that is   called server components. I also have a tutorial  video on server components that you can watch to   understand what they are. Server components, as  their name implies, they actually run entirely   on the server, they never make it to the client,  the only thingAnd here's what data fetching would   look like in that environment. So here, because  we're running this component on the server,   we actually get another benefit, which is that we  can make this an asynchronous component. We can   have this component be asynchronous, which means  that we no longer need to worry about rendering,   about different states, about loading states.  We can just have this asynchronous and literally   fetch the data in the body of the component. You  cannot do this with a client component. This only   works because this runs on the server. And then  we're getting right the response over here from   our fetch. We're doing the same exact thing.  Here, I just put a await promise to just make   it a little bit slower. You're going to see why in  just a moment. Then we're checking the response if   the response is okay. If it's not, we can throw an  error or we can redirect to somewhere else or we   can show some other UI to let the user know that  something went wrong. If the response is okay,   we get our post over here by doing another  await, the response.json. Again, this is the   same code that we had in the client component.  It's the same code as we have here, but we're   putting it directly in the body of the component  because this is an asynchronous server component.   And then we can just create some HTML, some JSX  over here, and just directly render out our post.   There's no loading, there's no pending, there's no  anything else. It's simple and you don't have to   use literally any dependency. So this is a huge  benefit of using server components if you can,   because it reduces a lot of the complexity  and you're doing things with a lot less code   and a lot less dependencies. Now granted, you are  losing a little bit of functionality, you have no   loading state. So in here, for example, while  this fetch request is happening, this component   is not going to get rendered because it doesn't  have data, it's awaiting the data, it's not going   to get rendered. I'm going to show you now how  to get around this, but it's something that you   have to know. You're in a different environment,  you're in the server environment, so things will   work a little bit differently. So you're losing  some complexity in one way, and you're adding   a little bit of complexity in the other way. But  honestly, it's a net positive. So let me now show   you all of these examples. So we can see how they  all behave, right. So I have all my components   over here. And let's start with fetch example  number one. So we're going to put this here,   we're going to go back to our application, we're  going to make things a little bit simpler, and   we're going to reload and see what happens. So you  see, we have loading for a split second, if I can   just maybe, let's see, go to my network over here,  and then make it fast 3g to make things a little   bit slower, we're going to see that I mean, it's  mostly the same, but fair enough, we have loading,   and then we have our data, if I increase the page,  it's going to load again, if I increase the page,   it's going to load again. But if I go back to  a page that everyone to one or three, actually,   there's a bug, let me just fix this one second,  this should not be plus one, this should be minus   one, there we go, we're going to refresh. So we're  going to increase the page from zero to one, we're   going to be in one, then I'm going to go back  to zero. And we're still fetching the same data   over again, right, there's no caching, as I've  mentioned, so this is fetch example number one,   then if we comment this out, we comment fetch  example number two, we go back here, we refresh,   we have the same URL. Now I'm going to go here  to page one, I'm going to go back to page zero,   and the results are much faster. I know it's  a little bit harder to see over here. Wait,   no, that was wrong. That was wrong. We're still  incrementing the page, I have the same bug in both   components. That's really funny. Let's save. And  let's start over again, ignore that this happened,   I'm going to leave this in. So we're on page zero,  we're going to press increment, we're page one,   then we go to page zero. And you see, there  was no loading, nothing flickered, we go back   to page one. And now I can change the pages. And  we're getting the results from the cache, this   is better, this is a better user experience, it's  better for our back end. And it's better overall.   But then if I go to page two, we haven't fetched  that page yet. So we're going to get the data.   But then I go back to one, go back to two, two  is also cached, right? This is how fetch example   number two works. And finally, let's try fetch  example number three, this is the asynchronous   server component. So we're going to come here  and refresh, right? And now this is going to   take a little bit longer. But you're going to  see there's no loading, there's no flickering,   our actual entire page is waiting, you see here at  the top, it's loading, it's loading until we get   the data back from a server component, right? So  server component, again, doesn't have rendering,   it's not actually running on the client, all  that we get is the HTML once the server component   actually finished running, right? So that's  how it works by default without doing anything   else to it. Now, if you want to add loading to  this component, which honestly you would write,   because we don't want to have less functionality  than we had before, then what you would do is   you would use suspense. So I can comment this  out over here, I can comment the suspense. And   suspense is a component in react that essentially  creates a boundary around a component, and then   will actually not prevent the entire component,  everything else of this home component over here   to block while it's waiting for that it is going  to create a boundary, and only this part is going   to block while the rendering of fetch example  three happens. And one of the cool things is   you can provide a fallback to display while that  is happening. And you can show here the loading   indicator, right? So let's see how that looks  like. So now with this code, if I reload the page,   you're going to see loading while the page is  actually loading. And once the component renders,   and it actually does everything that it needs  to do, we're going to see our data, right,   we have the same functionality as we had before,  but we're doing things a little bit differently,   right? So this is what data fetching looks like  in a server component. Now, one important thing   about fetching data in server components is,  as you can see here, we no longer have a state   variable for the page, we're no longer refetching  things when the page changes. That's because we're   in a server component, there is no state, there  is no re rendering the page, if we want to have   the same functionality, we'll now have to go in  the URL. And based on the URL, we will actually   get the page to fetch in the server component. And  then the caching over here, we also don't have it,   the caching will no longer be have to implemented  by a library they're using, but rather by the   framework of choice they're using to run your  server components. Most probably nowadays,   Next.js Next.js has a lot of caching, and they do  this based on the URL, right? So these are small   details. But really, it's ultimately the same  thing. It's just a different way, a more efficient   way of doing the same thing. We're fetching  the same data using the same properties, we're   just doing it in a slightly different way. And  honestly, I mean, this is really all they need to   be able to fetch data in your react applications.  And now you know how to do it all, you know how to   fetch data in a server component, you know how  to fetch data correctly in a client component   by using react query or something similar. And  you also know how to not fetch data, how to not   fetch it incorrectly in a client component. And  more importantly, you also know why not to do   this and why you should do this instead. So now no  matter what project you're working on, no matter   what they use to actually fetch the data, you know  the best practices, you know what to do what not   to do. And you're hopefully a better developer.  And now you know everything that there is to know   about data fetching in react, you enjoyed this  video and you want to see more videos just like   this one, make sure to leave this video a big  thumbs up. You can also click here to subscribe   or you can click here to watch a different video  of mine that YouTube seems to think that you're   really going to enjoy. And with that being said,  my name has been Darius Cosden, this is Cosden   Solutions. Thank you so much for watching and  I will see you in the next video. Ciao, ciao.