We modified the SignInPage to use
a React Query mutation when calling the API to log in.
And this works fine, except for one thing.
If we're signed out,
and we need to reload the page,
Incidentally, this other quirk with the Sign Out
is a separate issue, but is actually quite similar.
Anyway, what we want to tackle in this video
is that if we sign in,
we're sent to the HomePage,
but the NavBar still thinks we're not authenticated.
This is despite the logs showing that
the login request clearly succeeded,
and in fact it returned the "user" details.
So, as I mentioned in the previous video,
this happens because
when we fetch the "user" data
we use a query with a "staleTime" of 30 seconds.
So when we first load the page
and we're not authenticated,
"user" will be "undefined",
and that value will be cached.
Even if we sign in later,
the NavBar will keep using the cached value,
until that data expires, or we reload the page.
To fix this problem we basically need a way
to update the "user" value in the cache
after we sign in.
We can manipulate the React Query cache directly
by using the "queryClient",
that we can access from any component
by calling this "useQueryClient" hook.
So this hook returns the "queryClient",
that by the way is the same instance
we created in our custom App component.
Anyway, now that we have this "queryClient"
we can use it after we get the login response.
To update the cache we can call
the "setQueryData" method.
Here we need to pass the query key,
that in this case should be exactly the same string
that we used when calling "useQuery",
because we want to update the value
that we first fetched using that query.
Then we can pass the new value,
that in this case can be the "user" object
returned by the API request.
Note that we can put this "user" value
into the cache because
the "login" API route returns
the same kind of object as the "user" route.
Now let's save, and go and test it,
by signing out first.
And then signing in again,
with the usual details.
But I also want to show you what happens
in terms of network requests.
Let's clear them all,
so we can easily see any new requests.
Ok. If we sign in now,
first of all we can see that this time
the NavBar is immediately showing the new state.
We are signed in, so it's displaying
the user name and the "Sign Out" button.
Now, looking at the network requests
it made a "login" request, which is obvious
because that's what happens when we click "Sign In".
But the interesting thing is that
it didn't make any "user" request,
and yet the NavBar is showing the new user data.
If we look at the console we can see that
"user" was initially "undefined",
until we signed in, at which point
the NavBar was re-rendered
with the "user" data for Alice,
because that's what we got from the "login" route
and we manually put that value into the cache.
If we navigate to a new page,
you can see that again
the NavBar was rendered with "Alice" as the user,
so that's the value returned by "useQuery".
But if we if we go back to the network tab
it still didn't make any requests
to the "user" route,
because it's still getting the data from the cache.
So by writing the value directly into the cache
after we sign in
not only we make sure that
the data is updated immediately,
and the new user details
will be displayed in the NavBar.
But we also avoid making a separate request
to the "user" API route,
because we can use the data
returned by the "login" route instead.
Modifying the query cache directly
is a very powerful technique
once you get the hang of it.