Check out a free preview of the full Complete Intro to React, v9 course
The "Past Orders API" Lesson is part of the full, Complete Intro to React, v9 course featured in this preview video. Here's what you'd learn in this lesson:
Brian implements the Past Orders page. A getPastOrders module is created to load the order data from the API server. TanStack Query fetches the data, caching the responses with a stale time of 30 seconds.
Transcript from the "Past Orders API" Lesson
[00:00:00]
>> Brian Holt: Inside of our directory here, inside of our source directory outside of routes, create another folder called API. This is just something I do, not even just a React specific thing, this is just kind of across many things. I write my API request is just little individual functions and then I'll import those to be used later and that works really well with temp stack query.
[00:00:27]
You don't have to do it this way I'm just gonna show you the way that I would typically go about structuring this. So inside of this, make a file and call it getPastOrders and call it dot JSX. I think in my notes I have a dot JS we'll just stick with that, doesn't matter.
[00:00:46]
Export default, async function getPastOrders, and it takes in a page cuz it's paginated, right? Const response equals await fetch, and then this is gonna go to slash API slash past-orders, page, equals page. This is a template string, so make sure using back ticks here which is the one next to the one on the same key as the tilde.
[00:01:26]
>> Brian Holt: And then this will put in the page whatever we got there. And then we will say const data equals await response.json and return, data. Fairly straightforward here, it's gonna go out to the API. You're gonna give it a page, it's gonna call past-orders, it's gonna give it a page.
[00:01:50]
And then you are gonna get data back from this. So it's just gonna be a promise that eventually gives you back past-order data based on a page.
>> Brian Holt: Okay, cool, let us go back to past dot lazy, dot JSX.
>> Brian Holt: Yeah, one thing I was gonna say about the getPastOrders function here, we're gonna use it with Tanstack Query, but obviously you could use this anywhere, right?
[00:02:20]
This doesn't have to be used with Tanstack Query. This could be used in an effect, right? Or in your testing, or whatever you want, right? It's nice to encapsulate the logic and kind of small, reusable pieces of information there, past dot lazy, dot JSX. Let's go make this component here.
[00:02:38]
So make a function down here, to be called PastOrdersRoute, and I'm gonna call this just PastOrdersRoute like that.
>> Brian Holt: This one, I'm a little bit more like having the named function here, which is why I'm not just putting it directly here in component. Having what page it happened on in your stack trace tends to be more useful, more often than not.
[00:03:07]
Up here, we're gonna import useState, which we're gonna use to encapsulate the page that we're on from React. We're gonna import this wonderful new hook called useQuery, from @tanstack/react-query.
>> Brian Holt: And we're gonna import,
>> Brian Holt: GetPastOrders from API getPastOrders.
>> Brian Holt: Okay, let's take care of that, we're gonna get a hook here for the page.
[00:03:43]
Page setPage that should look familiar to you, equals useState, and we will start them on page 1.
>> Brian Holt: And const is loading and data, equals useQuery. So a couple of things here, we have to give it a queryKey.
>> Brian Holt: This is an array, and it's like, how many of you have ever used Redis before?
[00:04:18]
Probably asking the wrong crowd here. [LAUGH] But Redis much functions the same way that you kind of give out these queryKeys, and it's how it stores it in the cache, right? And then later, you can say hey, I'm looking for the past-orders, and then I'm looking for the page, right?
[00:04:35]
This is a unique thing to this query so that it knows later when it goes, hey, I'm looking for past-orders page two, it's gonna be like, I have seen that before, here you go, or I have never seen this before, here you go. Or another thing you can say, I've seen this before, but my cache is stale, so I'm gonna go get it again, right?
[00:04:53]
That's what this queryKey is for, it's for the name of the key in the cache. And if you're interested in Redis, Redis works a lot the same way.
>> Brian Holt: Okay, you're gonna give it a query function, and you're just gonna say, all right, give me back, getPastOrders with page.
[00:05:21]
>> Brian Holt: And then staleTime, I think I gave it a 30-second staleTime. Why such a short staleTime? This is in milliseconds by the way, that's why it's 30,000. All right, so imagine your pizza here and you are looking at past-orders, and this is how you put your orders together.
[00:05:40]
You want it to be pretty up to date, right? Because you wanna see the piece of the orders as they're rolling in. So I had it expiring every 30 seconds, so that you can always be guaranteed every 30 seconds you're getting a fresh pun in kind of intended there.
[00:05:57]
Look at the pizzas, right? But if you're going back and forth a bunch of times, you don't wanna just hammer the API, right? So it makes sense that you would have a little bit of cache time there. So 30 seconds felt right to me, but this is how you would adjust it, right?
[00:06:12]
There's other things, in fact, one of them that we're gonna about to do, we're gonna cache for a whole day because the past-orders don't change, and we don't really need to refresh those very often. So it all depends on your needs, caching in general is just kind of is hard, it's hard to figure out how long things should be good for.
[00:06:33]
So kind of a guess and check kind of situation. If I had to guess, most major bugs throughout my career have been caused by caching issues. Is that fair to say? I think that's pretty fair to say. All right, so if isLoading, this is another nice thing about React Query.
[00:06:53]
There's a bunch of them, there's like isSuccess, isFetched, isLoading, isPaused, isPending, isPlaceholderData, isRefetchError, they give you a bunch of different things here. You can also just grab the status I think, this is an enumerated type as opposed to being a Boolean, right? So you can also use that as well.
[00:07:13]
If David Khourshid was here, the guy that does, X State to be very happy that you could make a state machine. I am not gonna make a state machine because I'm not a nerd. That's not true, I am a nerd, he's probably less nerdy than I am. But, whatever fight me, David, that's fine.
[00:07:31]
So if isLoading,
>> Brian Holt: Return, div className equals past-orders.
>> Brian Holt: And we're gonna have, again, my very, very user experience focused loading here. I hope you get that, I'm being facetious here. You should have a much better loading state than just returning loading here. But I didn't wanna spend half of our time building loading pages, so that's why we're doing this.
[00:08:02]
Please, care more about your users than I care about you, no, I'm just kidding. [LAUGH] That's a joke. I do care deeply about each and every one of you.
>> Brian Holt: I woke up and chose violence today. Okay, here we go, return. So if it's not loading, then we can assume that our past-orders have loaded and we can just make a nice little table here of all of our past-orders.
[00:08:25]
Feel free to just go into there and just copy all of the markup here, but I'm gonna write it here by hand if you wanna follow along, that's cool too. We've had no problems with me forgetting divs or anything like that, so I'm very confident this time will be no different.
[00:08:40]
>> Brian Holt: Table, thead fed, as I like to say.
>> Brian Holt: Table row, table definition ID. So these are our head rows, this is an ID, this is a date, this is a time, okay? And then out of the fed there's the body as, it is said.
>> Brian Holt: Then, we're gonna say data, we're gonna get map across our data and make those into, rows map order.
[00:09:23]
>> Brian Holt: You can make this into the return blah, right? And use curly braces there, but because I'm lazy, if you use parentheses here, you can use the implicit return. I think I've used that here previously, but we're gonna do that again here. That's why this is a parentheses instead of a curly brace.
[00:09:44]
>> Brian Holt: And in this case, in case you're wondering, the parentheses in itself, doesn't do anything, it just means continued on the next row, right? That's why the parentheses ends up being put here.
>> Brian Holt: You definitely could do something, just put the thing directly on the same row, but this looks nicer, just so we'll do it this way.
[00:10:00]
All right, tr, we have to give the key.
>> Brian Holt: And a good key for this is order, order ID,
>> Brian Holt: Okay, and then td.
>> Brian Holt: We're gonna do order.order_id, couple of those. Next one will be date, next one will be time.
>> Brian Holt: Okay, that should give us our rows and our tables.
[00:10:40]
So outside of the tbody and the table, we're gonna have another div here and this is gonna be called pages.
>> Brian Holt: And we're just gonna give some basic pagination buttons here. So button disabled equals page is greater than or less than and equal to 1. So again, this is just my font combining the two into one thing, but it's less than or equal to 1.
[00:11:16]
>> Brian Holt: Okay, onClick equals setPage, that's a function, setPage, page minus 1.
>> Brian Holt: And we'll put previous here, and then the next one looks really similar, so I'm just gonna copy and paste the whole block here. So the disabled, I know these come in lengths of 10, and I didn't wanna make the API any more complicated than this, so I said data.length is less than 10.
[00:11:50]
Because if it returns eight results, you've reached the end, right? The only problem is, what if there's exactly ten left? You're gonna get a page of zero after that, again, phenomenal user experience. You should definitely listen to me and hire me to consult at your company. That's a joke, that's a terrible idea.
[00:12:08]
But this is what we are doing, so this should be minus 1 here, so there should be a space here on line 46. And as the same here, there should be a plus 1, there should be a space there.
>> Brian Holt: And then we, instead of previous here, we're gonna have next.
[00:12:31]
>> Brian Holt: There's some thousands of orders in the database, so unless you're very bored, want to page through all of them one day. I don't think many people are gonna find the end of this and discover what a terrible experience this is. I think that should be enough for us to see if it works.
[00:12:51]
So past-orders, we made this button previously, so I think if we click on that, it's gonna load.
>> Brian Holt: It did okay, cool. So you can see here, throughout the course here, I've submitted two orders here, which is pretty cool cuz you can see those are in 2024. I grabbed a dataset off of Kaggle for pizza orders, that's why all these are from 2015.
[00:13:23]
We're not time traveling in the past right now. And you're like, how is he talking about React 18 and 2015? It's cuz I knew, I'm just kidding. There you go, so you can see these are taking a while. Did I leave that, let's just check in my API, I think I might've left the weight in there, that's funny.
[00:13:44]
All right, but now, if I hit previous, what's gonna happen? Notice that these loads are instant between these two that I've loaded before. But if I hit Next again, it's gonna load it again, so it's going back to the API. Yeah, I think I put artificial delay into this API so that people could tell the difference.
[00:14:06]
But now look at your open, your TanStack dev tools, you can see these being used here. So if I do next, it's gonna show you things I have in my cache here, and that it's gonna go out and get this one. You can click on that, I think, and you can see what the key is.
[00:14:27]
This only has one observer, but if you had a bunch of things that were looking at these cache keys, it would look at that as well. And you can see what it came back with, the actual data, right? The order ID, date, time, all sorts of really cool stuff.
[00:14:43]
Pretty useful, I use the DevTools for this one somewhat frequently.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops