1
00:00:03,000 --> 00:00:06,225
We extracted this custom "useUser" hook,

2
00:00:06,726 --> 00:00:10,250
so that in the NavBar we can get the "user" data

3
00:00:10,250 --> 00:00:12,233
with a single line of code.

4
00:00:12,807 --> 00:00:15,208
Now let's look at a another example

5
00:00:15,208 --> 00:00:16,649
of using React Query.

6
00:00:17,217 --> 00:00:20,940
In the SignInPage we call the "/api/login" route,

7
00:00:20,940 --> 00:00:23,295
so this is another HTTP request

8
00:00:23,295 --> 00:00:26,257
where we could use React Query instead.

9
00:00:26,257 --> 00:00:29,828
But note that in this case it's a POST request,

10
00:00:29,828 --> 00:00:31,955
not a GET like when we fetch

11
00:00:31,955 --> 00:00:34,081
the user data in the NavBar.

12
00:00:34,081 --> 00:00:37,196
Also, here we're only sending the request

13
00:00:37,196 --> 00:00:40,159
when the user clicks the submit button,

14
00:00:40,159 --> 00:00:43,273
while in the NavBar we load the user data

15
00:00:43,273 --> 00:00:46,008
as soon as the component is mounted.

16
00:00:47,192 --> 00:00:50,088
For these reasons, instead of "useQuery"

17
00:00:50,088 --> 00:00:52,913
in this case we'll use a different hook

18
00:00:52,913 --> 00:00:54,434
called "useMutation".

19
00:00:55,079 --> 00:00:57,953
But by using React Query we'll also be able

20
00:00:57,953 --> 00:01:00,093
to remove this "status" variable

21
00:01:00,093 --> 00:01:02,633
that we added to keep track of whether

22
00:01:02,633 --> 00:01:04,305
the request is "loading",

23
00:01:04,305 --> 00:01:06,043
or failed with an "error".

24
00:01:06,811 --> 00:01:08,316
Let's open the Sign In page,

25
00:01:08,816 --> 00:01:11,423
which means we'll need to sign out first.

26
00:01:11,923 --> 00:01:14,251
And we still need to refresh the page

27
00:01:14,251 --> 00:01:16,391
for it to detect we're signed out.

28
00:01:16,391 --> 00:01:18,278
I promise we will come back to

29
00:01:18,278 --> 00:01:20,481
this issue with the Sign Out button

30
00:01:20,481 --> 00:01:22,432
before the end of this section.

31
00:01:23,183 --> 00:01:25,590
But anyway, we can now go to the Sign In page.

32
00:01:26,090 --> 00:01:28,263
And we can start modifying our code.

33
00:01:28,990 --> 00:01:32,274
As I mentioned in this case we want to call

34
00:01:32,274 --> 00:01:33,343
"useMutation",

35
00:01:33,343 --> 00:01:36,703
that's another hook provided by React Query.

36
00:01:36,703 --> 00:01:39,223
The difference between "useQuery"

37
00:01:39,223 --> 00:01:41,132
and "useMutation" is that

38
00:01:41,132 --> 00:01:44,339
"useQuery" is to fetch data straight away,

39
00:01:44,339 --> 00:01:47,012
and usually cache the data as well,

40
00:01:47,012 --> 00:01:49,455
so typically you call "useQuery"

41
00:01:49,455 --> 00:01:51,593
when you make a GET request.

42
00:01:51,593 --> 00:01:55,411
While with "useMutation" we define a request here,

43
00:01:55,411 --> 00:01:57,855
but we'll only execute it later,

44
00:01:57,855 --> 00:02:01,826
in this case when the user clicks the submit button.

45
00:02:01,826 --> 00:02:04,498
And "useMutation" is typically used

46
00:02:04,498 --> 00:02:07,782
with POST requests, or maybe PUT or DELETE.

47
00:02:07,782 --> 00:02:10,149
But in any case with a mutation

48
00:02:10,149 --> 00:02:12,669
we are calling the API to modify,

49
00:02:12,669 --> 00:02:14,425
or "mutate", some data.

50
00:02:14,425 --> 00:02:16,487
While when making a "query"

51
00:02:16,487 --> 00:02:19,465
we just want to GET some existing data.

52
00:02:21,340 --> 00:02:24,302
Now, as argument to "useMutation" we pass

53
00:02:24,302 --> 00:02:26,904
a function to make the HTTP request.

54
00:02:26,904 --> 00:02:29,216
This is like the second argument

55
00:02:29,216 --> 00:02:30,806
we pass to "useQuery".

56
00:02:30,806 --> 00:02:33,262
But notice that with "useMutation"

57
00:02:33,262 --> 00:02:36,442
we don't pass a "key" as the first argument,

58
00:02:36,442 --> 00:02:39,549
because the "key" is used to cache the data

59
00:02:39,549 --> 00:02:41,139
returned by the query.

60
00:02:41,139 --> 00:02:44,318
But a mutation may not even return any data;

61
00:02:44,318 --> 00:02:47,281
we could just DELETE an item for example.

62
00:02:47,281 --> 00:02:50,894
So by default a mutation doesn't affect the cache.

63
00:02:52,117 --> 00:02:54,481
Anyway, the code to make the request

64
00:02:54,481 --> 00:02:57,699
will be similar to what we had in "handleSubmit",

65
00:02:58,265 --> 00:03:00,357
but in this case we want to return

66
00:03:00,357 --> 00:03:02,266
the data we fetch from the API.

67
00:03:02,266 --> 00:03:04,174
Now, we have a single statement

68
00:03:04,174 --> 00:03:05,467
inside this function,

69
00:03:06,152 --> 00:03:09,069
so we could actually simplify this code a little,

70
00:03:09,069 --> 00:03:10,974
and return "fetchJson" directly,

71
00:03:12,952 --> 00:03:15,845
without having the function body inside brackets.

72
00:03:17,452 --> 00:03:19,091
This is exactly the same thing,

73
00:03:19,091 --> 00:03:20,943
but we made our code a bit shorter.

74
00:03:21,496 --> 00:03:23,979
Now, "useMutation" returns an object

75
00:03:23,979 --> 00:03:26,808
that unsurprisingly I'll call "mutation".

76
00:03:27,377 --> 00:03:30,530
And this mutation object has various properties,

77
00:03:30,530 --> 00:03:32,435
many of them similar to those

78
00:03:32,435 --> 00:03:34,865
of the object returned by "useQuery".

79
00:03:35,497 --> 00:03:37,994
One of these properties is "isError",

80
00:03:37,994 --> 00:03:40,626
that can tell us if the request failed.

81
00:03:41,194 --> 00:03:43,852
And below there's also "isLoading".

82
00:03:44,352 --> 00:03:47,194
So the mutation object already includes

83
00:03:47,194 --> 00:03:49,600
some "loading" and "error" flags,

84
00:03:49,600 --> 00:03:52,662
similar to those we kept in this "status".

85
00:03:53,308 --> 00:03:56,116
Which means we can now delete that state variable,

86
00:03:56,974 --> 00:03:59,267
and instead of "status.error"

87
00:03:59,267 --> 00:04:01,640
we can use "mutation.isError".

88
00:04:02,220 --> 00:04:04,899
Similarly, replace "status.loading"

89
00:04:04,899 --> 00:04:06,889
with "mutation.isLoading".

90
00:04:07,466 --> 00:04:11,177
Both "isError" and "isLoading" are boolean values.

91
00:04:11,677 --> 00:04:14,218
And since the mutation keeps track of that,

92
00:04:14,718 --> 00:04:17,976
we can also remove all the calls to "setStatus".

93
00:04:19,218 --> 00:04:20,857
Now, in this "catch" block

94
00:04:20,857 --> 00:04:22,813
let's add a comment saying that

95
00:04:22,813 --> 00:04:25,651
in this case "mutation.isError" will be true,

96
00:04:25,651 --> 00:04:28,426
just to explain why we're not doing anything

97
00:04:28,426 --> 00:04:29,309
in this block.

98
00:04:30,062 --> 00:04:32,876
Ok. Now, we also need replace the code

99
00:04:32,876 --> 00:04:34,950
that makes the HTTP request,

100
00:04:35,525 --> 00:04:38,434
otherwise there's no point in using "useMutation".

101
00:04:38,934 --> 00:04:41,114
The "mutation" object provides

102
00:04:41,114 --> 00:04:44,240
a couple of methods to execute the request,

103
00:04:44,240 --> 00:04:46,711
called "mutate" and "mutateAsync".

104
00:04:47,357 --> 00:04:49,967
I pretty much always use the "async" one,

105
00:04:50,467 --> 00:04:53,615
because with this we can get the response data

106
00:04:53,615 --> 00:04:56,147
by "awaiting" the Promise it returns.

107
00:04:56,716 --> 00:04:59,033
And I called it "user" here because

108
00:04:59,033 --> 00:05:00,688
that's what this data is,

109
00:05:00,688 --> 00:05:03,668
it's what the "/api/login" response contains.

110
00:05:04,301 --> 00:05:06,709
Ok, so I think we're ready to save

111
00:05:06,709 --> 00:05:08,409
and test if things work.

112
00:05:08,980 --> 00:05:12,256
Let's try signing in, as "alice@example.com"

113
00:05:12,756 --> 00:05:15,163
but let's start with a wrong password.

114
00:05:15,163 --> 00:05:17,760
We get the "Invalid credentials" message,

115
00:05:17,760 --> 00:05:18,837
which is correct.

116
00:05:18,837 --> 00:05:20,928
And, I don't know if you noticed,

117
00:05:20,928 --> 00:05:23,462
but for a split-second it also displayed

118
00:05:23,462 --> 00:05:24,792
the "Loading" message

119
00:05:24,792 --> 00:05:26,946
while the request was in progress.

120
00:05:27,827 --> 00:05:30,479
Now, let's try with the right password,

121
00:05:30,479 --> 00:05:31,703
that's "Alice123".

122
00:05:33,427 --> 00:05:35,211
And we're sent to the HomePage,

123
00:05:35,211 --> 00:05:37,398
which means the log in was successful.

124
00:05:37,956 --> 00:05:41,330
But the NavBar still shows the "Sign In" link.

125
00:05:41,330 --> 00:05:43,017
That's not quite right.

126
00:05:43,017 --> 00:05:45,217
Can you guess why that may be?

127
00:05:45,217 --> 00:05:48,152
As a hint, that's actually nothing to do

128
00:05:48,152 --> 00:05:51,012
with the changes we made in this video.

129
00:05:51,012 --> 00:05:52,920
We introduced this problem

130
00:05:52,920 --> 00:05:56,220
when we changed the NavBar to use "useQuery".

131
00:05:56,220 --> 00:05:58,494
What's happening is simply that

132
00:05:58,494 --> 00:06:00,915
we configured "useQuery" to cache

133
00:06:00,915 --> 00:06:03,189
the "user" data for 30 seconds.

134
00:06:03,189 --> 00:06:06,930
So it will keep using the cached value for a while.

135
00:06:08,164 --> 00:06:09,590
In the next video we'll see

136
00:06:09,590 --> 00:06:10,753
how to fix this issue.

137
00:06:11,306 --> 00:06:13,758
But for now, if we reload the page,

138
00:06:13,758 --> 00:06:17,052
we can see that at this point we are signed in,

139
00:06:17,052 --> 00:06:19,855
which means the login request succeeded.

140
00:06:20,496 --> 00:06:23,281
So the request we make with the "mutation"

141
00:06:23,281 --> 00:06:24,674
is working correctly.

142
00:06:25,241 --> 00:06:28,998
And this is a first example of using "useMutation".

143
00:06:28,998 --> 00:06:31,060
We simply pass it a function

144
00:06:31,060 --> 00:06:33,933
that knows how to make the API request,

145
00:06:34,581 --> 00:06:36,495
then we call "mutateAsync"

146
00:06:36,495 --> 00:06:39,735
when it's time to actually send the request,

147
00:06:39,735 --> 00:06:42,018
and this asynchronously returns

148
00:06:42,018 --> 00:06:44,890
any data contained in the API response.

149
00:06:45,611 --> 00:06:48,518
What's more is that the "mutation" object

150
00:06:48,518 --> 00:06:50,788
already provides flags to detect

151
00:06:51,359 --> 00:06:52,980
if the request is "loading",

152
00:06:52,980 --> 00:06:54,544
or if there was an "error",

153
00:06:55,102 --> 00:06:57,131
so we don't need to worry about

154
00:06:57,131 --> 00:06:59,749
keeping track of those states ourselves.

155
00:07:00,315 --> 00:07:02,680
In the next video we'll see how to

156
00:07:02,680 --> 00:07:05,880
update the NavBar state as soon as we sign in,

157
00:07:05,880 --> 00:07:09,149
fixing that problem we identified a minute ago.

