In the previous step we created
this "useSignIn custom hook,
that takes care of making a login request
and also update the "user" value
in the React Query cache.
By the way, both this hook
and the "useUser" hook
use the same query key for the "user" data.
So it's a good thing that
we have both of them in the same module.
In fact, we could extract a common constant,
let's call it "USER_QUERY_KEY",
and then use this constant
instead of the string literal,
so it should be absolutely clear
to anybody reading this file that
we must use the same key in both places.
Ok. That was just a quick refactoring.
What I want to do in this video is
finally fix that problem with the sign out.
As we've seen a number of times,
ever since we started using useQuery in the NavBar
if we click "Sign Out", the NavBar doesn't
immediately update to reflect the new state,
and we always had to reload the page
for it to show that we're now signed out.
So, to resolve this issue, we'll want to use "useMutation" for the "logout" request,
just like we do for the "login".
But in the mutation function of course
we should call "/api/logout" instead.
And after we logout we also want to
update the "user" value in the React Query cache,
like we do after we sign in.
We also know by this point that
every time we make an API request
it's good to encapsulate that logic
in a custom hook.
So let's write a new hook function,
that we can call "useSignOut".
If you feel like doing some exercise
you can try implementing this function yourself,
since I already outlined what we should do here,
and there are no new concepts you need to be aware of.
So if you want to try this, pause this video now,
and write the code for this function,
otherwise I'll continue with the implementation.
Ok. Let's go ahead.
The first thing we want to do is call "useMutation",
to prepare the "logout" request.
And to actually make the HTTP request
we can simply call "fetchJson",
like we previously did in the NavBar.
Let's assign the result to a "mutation" variable.
What requires a little bit of thought is:
what should we return from here?
I think we should return a function.
This way when we use that hook,
we can call "useSignOut",
and obtain the returned function,
that we can name "signOut".
So then, when the user clicks the button
we can simply call that "signOut" function.
In fact, at this point it's not even worth
having a separate "handleSignOut" handler.
We could just pass "signOut" directly
as the "onClick" event handler.
Which means we can remove
this other function altogether.
At this point we can also remove
the "fetchJson" import.
Ok, so this simplifies our NavBar code,
but we haven't actually implemented
this "signOut" function yet.
What we want to do here is make the API request
by calling "mutation.mutateAsync()",
and we can "await" for that request to complete.
Because after that we want to
update the value of the "user" data
in the React Query cache.
So that's the same thing we did in "useSignIn".
We first need the "queryClient" instance
that we can get by calling "useQueryClient",
and then we want to call
"queryClient.setQueryData".
But in this case, since we signed out
the "user" value should be "undefined".
This way as soon as the user signs out
the NavBar should reflect the new state.
Let's see if this actually works.
We'll need to sign in first, before we can sign out.
So let's enter the usual credentials,
and I'll reload the page as well, just in case.
Now, before I click "Sign Out",
let me show the Chrome Developer tools
so we can look at the network requests.
Ok. Let's click sign out,
and this triggered a "logout" request,
so the mutation worked.
But this time the NavBar also re-rendered itself,
showing that the "user" data managed by React Query
was updated correctly.
"user" will now be "undefined",
because that's the value we put in the cache.
And even if we navigate to different pages
it will continue to use that cached value,
without making any new requests to the "user" route.
Ok. So we proved that our new code works.
And this is my implementation
for our "useSignOut" custom hook.
If you tried implementing it yourself,
hopefully you did something similar.