All right.
And now let's see how we can implement the React query in the loader.
And as a side note, this is where things get clunky, so just bear with me.
For starters, I want to set this object separately because we will use it in two places.
And also remember, Axios is already returning data.
And therefore we go here with data dot data.
And if we want to avoid that effectively, we can set this function as async await inside of the function.
We can wait for response data and then return that one.
Long story short, we can just access default stats and monthly applications directly from the data.
So let's go above the loader and in my case, I'm going to call this stats query.
That's going to be my object.
And as far as what do I want to add there?
Well, I want these two properties.
And like I said, I'll make this one a sink and then it's not going to be implicit return.
Actually, we'll have the curlies and the return.
And then first let's wait for response so that one is going to be equal to await.
Then we grab here this custom fetch and then we want to return response data.
Again, this is Axios thing.
We get back this giant object and we're looking for the data.
Now in here, we're actually going to pass in that stats query.
And now, again, we don't need to do that dot data.
Now also we're not going to use this is loading and is error because we'll have react query in the loader
so we can nicely skip these two things over here.
Again, at the moment there's going to be an error because we'll try to grab default stats and monthly
applications from the data.
Don't worry about it.
Once we fix it, everything is going to be correct.
So at the moment, yes, you will have an error.
Now how we can start using a React query and as a note, I can actually remove these ones as well since
we won't use it.
So how we can start using React query in the loader?
Well, we have the hook.
Correct.
But here's one major.
Gotcha.
Loader is not a hook.
And one of the rules of the hooks is that you can only call hook in the component or in a custom hook.
And that's why we always set up custom hooks with use and whatever the name.
Now, loader is not a hook.
So we cannot directly come here and say, Hey, use query and let's return a data.
That's not going to work.
So this is where we'll have to pass the query.
Client Remember the one that we set up in the app directly into our loader?
So we're looking for stats loader and I want to access this query client our instance and then this
instance has the methods which we can also use to pretty much fetch the data with React query.
Now.
How we can pass the query client down to a loader.
Well, we'll have to invoke it and we pass in the query client.
But as things currently stand in the stats page, we'll have a massive error.
Why?
Well, because we invoke this stats loader right away.
So in order to fix it, we need to go back to the stats.
And this loader is going to become a function which returns a function.
So we go here, we'll have access to the query client and now everything is going to be correct.
Basically we invoke loader.
Yep.
We grab the query client and then from the loader we return the actual function.
And essentially I still return the same function.
We just have this extra step over here in order to access the query client.
And if we want to make a request with the query client, this is going to be the syntax.
So we start over here by setting up data.
Then the method we're going to use is going to be asynchronous and therefore we go with Await.
Then we go with query client.
So again, we have access to it because we pass it from App.jsx and then the method we're looking for
is ensure query data.
And this method is again looking for the same object.
That's why we set it up in two places.
So we pass over here the stats query and then.
From this loader.
We just return data.
Now, as a quick side note, technically you can return null as well, and I'll showcase that in a second.
So let's navigate back over here.
Again, I'll go to add Job.
Let me refresh.
Let me start from scratch.
You know what?
I'll make this one.
Smaller then let's go to a stats.
Notice initially we had that loading because again, we're using the loader right now.
Let me hop back to jobs then back to stats and notice again we get this data instantly and at the very
end, let me just showcase a few things.
For starters, let me navigate to App.jsx and I'm going to mess with the stale time.
So how long the query is going to be valid and I'm actually going to set it up as 10s.
Again, it's looking for milliseconds.
One second is 1000 milliseconds, and if I multiply 1000 by ten I'm going to get my 10s I don't think
I need to refresh.
Let me just go back to all jobs again.
We make the first request, the stats one and now for 10s we can navigate back and this is going to
be cached.
Now after those 10s you will see that the query is not going to be valid, which means that behind the
scenes React query is going to make a request in order to showcase that.
Again, let's navigate to a network.
I mean, now we have a bunch of things open over here, so let me close this one for now.
Again, let's start from scratch.
We refresh.
This is the page you navigate to the stats one now for pretty much 10s.
We can keep coming back.
We're not going to be making a request then in those 10s.
Query is going to turn stale.
So now if let's say I navigate again to all jobs and back to the stats, we will make the request.
Hopefully that is clear.
So now let me navigate back over here and I'll still multiply this by 60 and then back to five.
And I also want to discuss something students have been asking essentially, why do we even want to
call here this use query?
So why do we need to call this twice?
Can't we just access data using use loaded data and then call it a day?
And technically we can do that.
Let's try it out.
So I'm going to go over here.
Remember, we're returning a data, so now I can just access it here and you'll see that essentially
our functionality works, but we're losing some benefits.
You see, React Query is more than just caching, for example.
We also know Refetch on the autofocus.
So therefore, yes, you can technically skip it, but in my case I'll keep it in two places.
So I'll actually remove this and I'll comment these ones out.
Now lastly, I can go here with Null and everything is going to work because again, we're not really.
Using the data back from the loader is actually available over here.
So we invoke ensure query data, which effectively either grabs the data from the cache if it's still
valid.
If not, then it refreshes.
And if we have the data, then of course it's already right away available over here in this use query.
So now let's navigate back again.
I know probably some people find it annoying, but I do want to showcase this.
We go here and notice our query is still valid and we're good to go even though technically I'm returning
a null.
So we're not accessing this data from the loader.
Technically, we set up over here this query.
And since it's available in the query, in the stats query, since there is a data, of course I'll
have access to it over here as well.
And lastly, I just want to showcase that if we have some kind of error and I'm going to demonstrate
that by messing with the URL.
Of course, now we are displaying the error element so we can clearly see that we got back 400.
So there was some kind of issue with the request and therefore we trigger the error and as a result
we display heading four with our error text on the screen.