﻿1
00:00:01,440 --> 00:00:03,120
‫As our first custom hook,

2
00:00:03,120 --> 00:00:06,147
‫let's start with a hook called useMovies.

3
00:00:07,980 --> 00:00:11,250
‫So there are basically two strategies to decide

4
00:00:11,250 --> 00:00:14,370
‫if we want to create a new custom hook.

5
00:00:14,370 --> 00:00:15,330
‫So the first one

6
00:00:15,330 --> 00:00:20,250
‫is that we want to reuse some part of our non-visual logic,

7
00:00:20,250 --> 00:00:23,430
‫so just as we learned in the previous lecture.

8
00:00:23,430 --> 00:00:25,530
‫And the second factor might be

9
00:00:25,530 --> 00:00:29,910
‫that we simply want to extract a huge part of our component

10
00:00:29,910 --> 00:00:32,700
‫out into some custom hook.

11
00:00:32,700 --> 00:00:36,870
‫And so that's actually what we will do in this lecture.

12
00:00:36,870 --> 00:00:39,630
‫So we will take this useEffect here,

13
00:00:39,630 --> 00:00:42,300
‫which fetches our movie data,

14
00:00:42,300 --> 00:00:46,680
‫and we will extract it into a hook called useMovies.

15
00:00:46,680 --> 00:00:50,190
‫And so then we get rid of all of this code

16
00:00:50,190 --> 00:00:51,750
‫here in our component.

17
00:00:51,750 --> 00:00:53,100
‫And of course, if we wanted,

18
00:00:53,100 --> 00:00:57,033
‫we could then later reuse this hook in some other project.

19
00:00:58,290 --> 00:01:00,300
‫Okay, so in this lecture,

20
00:01:00,300 --> 00:01:04,050
‫I will show you how we can extract all the stateful logic

21
00:01:04,050 --> 00:01:05,550
‫that belongs together

22
00:01:05,550 --> 00:01:09,810
‫into a nice and well-packaged custom hook.

23
00:01:09,810 --> 00:01:11,850
‫So let's do that.

24
00:01:11,850 --> 00:01:13,320
‫And actually for that,

25
00:01:13,320 --> 00:01:18,320
‫I will create a brand new file here in our source,

26
00:01:18,480 --> 00:01:23,343
‫and I'll then call it useMovies.js.

27
00:01:26,190 --> 00:01:30,123
‫Okay, and from here, we will export a function,

28
00:01:31,200 --> 00:01:33,420
‫which is going to be our custom hook

29
00:01:33,420 --> 00:01:35,967
‫called exactly useMovies.

30
00:01:38,610 --> 00:01:40,830
‫Okay, and notice that here,

31
00:01:40,830 --> 00:01:45,120
‫I'm not doing an export default, but a named export.

32
00:01:45,120 --> 00:01:48,780
‫And so that's kind of a strategy that I like to use,

33
00:01:48,780 --> 00:01:53,780
‫so using default exports for components like this one here

34
00:01:54,810 --> 00:01:58,440
‫and using named exports for custom hooks.

35
00:01:58,440 --> 00:02:00,450
‫Now, that's not really mandatory,

36
00:02:00,450 --> 00:02:03,330
‫but that's just the way I like to do it.

37
00:02:03,330 --> 00:02:06,723
‫So you could, of course, also do a default export here.

38
00:02:08,400 --> 00:02:10,710
‫Okay, and so let's start

39
00:02:10,710 --> 00:02:14,013
‫by extracting these useEffect here,

40
00:02:14,880 --> 00:02:16,833
‫so this huge thing,

41
00:02:17,850 --> 00:02:19,260
‫and then we will notice

42
00:02:19,260 --> 00:02:23,130
‫that we will need a lot more stuff than just this

43
00:02:23,130 --> 00:02:24,483
‫here in this function.

44
00:02:26,530 --> 00:02:29,070
‫Okay, so give it a save, and immediately,

45
00:02:29,070 --> 00:02:33,600
‫we see that we are missing all of these state variables.

46
00:02:33,600 --> 00:02:36,690
‫So in this case, these state setError functions.

47
00:02:36,690 --> 00:02:39,000
‫And so that's because fetching the movies

48
00:02:39,000 --> 00:02:42,303
‫requires a lot more than just this effect.

49
00:02:43,500 --> 00:02:46,380
‫So notice how we actually also need

50
00:02:46,380 --> 00:02:48,063
‫multiple state variables.

51
00:02:49,920 --> 00:02:53,490
‫So the movies, isLoading, and error,

52
00:02:53,490 --> 00:02:55,200
‫all of them are necessary

53
00:02:55,200 --> 00:02:58,980
‫to make the functionality of fetching movies work.

54
00:02:58,980 --> 00:03:02,130
‫And so, let's also extract them from here

55
00:03:02,130 --> 00:03:05,073
‫and paste them where they're unnecessary.

56
00:03:06,570 --> 00:03:10,833
‫Okay, and then we just have some problems with importing,

57
00:03:11,730 --> 00:03:13,240
‫so import useState

58
00:03:15,642 --> 00:03:19,053
‫and useEffect from React.

59
00:03:20,610 --> 00:03:23,580
‫Okay, so that's looking already better,

60
00:03:23,580 --> 00:03:27,120
‫but we still have some missing information right here.

61
00:03:27,120 --> 00:03:30,093
‫So we're missing the key and we're missing the query.

62
00:03:31,050 --> 00:03:34,680
‫So to fix that, we can simply accept the query here,

63
00:03:34,680 --> 00:03:37,953
‫for example, as a parameter to our function.

64
00:03:40,740 --> 00:03:44,070
‫And so now, remember that this really is a function.

65
00:03:44,070 --> 00:03:45,600
‫This is not a component.

66
00:03:45,600 --> 00:03:48,030
‫And so here, we don't accept props,

67
00:03:48,030 --> 00:03:51,993
‫but really we accept arguments like this.

68
00:03:54,480 --> 00:03:58,440
‫So even though our custom hook is not yet going to work,

69
00:03:58,440 --> 00:04:02,217
‫let's already call it, so useMovies.

70
00:04:04,470 --> 00:04:05,303
‫And so then again,

71
00:04:05,303 --> 00:04:09,123
‫VS Code will automatically import this for us.

72
00:04:10,380 --> 00:04:13,350
‫So now you have this line of code here

73
00:04:13,350 --> 00:04:17,400
‫which again imports the custom hook that we just created.

74
00:04:17,400 --> 00:04:20,190
‫And notice how it's using here at a curly braces,

75
00:04:20,190 --> 00:04:24,480
‫meaning that this is a named export at a named import.

76
00:04:24,480 --> 00:04:28,380
‫But anyway, now here we are calling our new custom hook.

77
00:04:28,380 --> 00:04:31,890
‫And so let's pass the query in.

78
00:04:31,890 --> 00:04:33,210
‫All right,

79
00:04:33,210 --> 00:04:37,020
‫now we're not saving anything to a variable here just yet,

80
00:04:37,020 --> 00:04:41,250
‫because for now, our custom hook is not returning anything.

81
00:04:41,250 --> 00:04:43,413
‫And so let's actually change that.

82
00:04:44,550 --> 00:04:47,400
‫So what exactly should we actually return

83
00:04:47,400 --> 00:04:49,800
‫from this custom hook?

84
00:04:49,800 --> 00:04:52,950
‫Well, basically, we want to return everything

85
00:04:52,950 --> 00:04:55,590
‫that we need here in the app.

86
00:04:55,590 --> 00:04:56,423
‫So basically,

87
00:04:56,423 --> 00:05:01,020
‫all the variables that somewhere in our JSX are necessary.

88
00:05:01,020 --> 00:05:04,800
‫And so that's basically exactly the three pieces of state

89
00:05:04,800 --> 00:05:06,780
‫that we just removed from here.

90
00:05:06,780 --> 00:05:11,010
‫So it's the movies, the error, and the isLoading state,

91
00:05:11,010 --> 00:05:15,753
‫because again, we will need these somewhere here in our JSX.

92
00:05:16,740 --> 00:05:20,520
‫So we have movies, we have isLoading, and we have error.

93
00:05:20,520 --> 00:05:22,590
‫And so again, we, of course,

94
00:05:22,590 --> 00:05:27,120
‫now need access to these variables right here as well.

95
00:05:27,120 --> 00:05:30,270
‫And so that's basically what we will want

96
00:05:30,270 --> 00:05:33,180
‫this custom hook to return.

97
00:05:33,180 --> 00:05:36,663
‫And so, let's return them from here.

98
00:05:38,378 --> 00:05:40,980
‫So I think that's the correct place, yeah.

99
00:05:40,980 --> 00:05:44,640
‫So right after the useEffect, we will return,

100
00:05:44,640 --> 00:05:47,463
‫and we will place them all into one object.

101
00:05:48,570 --> 00:05:50,430
‫So it could be an array as well,

102
00:05:50,430 --> 00:05:53,310
‫but it's very common to just return an object

103
00:05:53,310 --> 00:05:56,280
‫especially when we have so many different things,

104
00:05:56,280 --> 00:06:00,933
‫like movies, isLoading, and error.

105
00:06:02,640 --> 00:06:06,210
‫All right, now here we actually have a problem now

106
00:06:06,210 --> 00:06:07,653
‫with this handleCloseMovie.

107
00:06:08,520 --> 00:06:11,043
‫So let's comment this out for now.

108
00:06:12,120 --> 00:06:14,970
‫And now there's only one thing that we are missing here,

109
00:06:14,970 --> 00:06:17,220
‫which is this key.

110
00:06:17,220 --> 00:06:20,490
‫And so let's grab this, so copying it

111
00:06:20,490 --> 00:06:23,073
‫and then pasting that here as well.

112
00:06:24,300 --> 00:06:26,610
‫So it could also have passed this in

113
00:06:26,610 --> 00:06:29,190
‫as an argument into the function,

114
00:06:29,190 --> 00:06:30,870
‫but I think that the key itself

115
00:06:30,870 --> 00:06:34,290
‫really should be part of this file here,

116
00:06:34,290 --> 00:06:39,090
‫because it is tightly coupled also to the movie URL.

117
00:06:39,090 --> 00:06:40,980
‫And so if we passed in the key,

118
00:06:40,980 --> 00:06:43,920
‫then we should probably also pass in the URL,

119
00:06:43,920 --> 00:06:45,990
‫but that we don't want.

120
00:06:45,990 --> 00:06:49,473
‫So we want to make this as reusable as possible.

121
00:06:50,820 --> 00:06:55,403
‫Okay, and so now, all we have to do is to then, here,

122
00:06:57,060 --> 00:07:00,000
‫basically get the data that is returned

123
00:07:00,000 --> 00:07:04,590
‫and destructure them here into their own variables again,

124
00:07:04,590 --> 00:07:09,563
‫so that's movies, isLoading, and error.

125
00:07:11,545 --> 00:07:12,963
‫And so that's actually it.

126
00:07:13,950 --> 00:07:15,030
‫So again,

127
00:07:15,030 --> 00:07:19,320
‫here we are returning these three pieces of information,

128
00:07:19,320 --> 00:07:20,850
‫so these state variables

129
00:07:20,850 --> 00:07:24,570
‫that we are going to need outside of this custom hook.

130
00:07:24,570 --> 00:07:28,620
‫And so, basically, then this returns an object,

131
00:07:28,620 --> 00:07:32,280
‫which we then immediately destructure right here.

132
00:07:32,280 --> 00:07:33,113
‫And so then,

133
00:07:33,113 --> 00:07:36,480
‫as far as the app component here is concerned,

134
00:07:36,480 --> 00:07:40,320
‫having this is exactly the same as having all the code

135
00:07:40,320 --> 00:07:43,170
‫that we had here in the component before.

136
00:07:43,170 --> 00:07:46,473
‫And so if we give this a save and try this now,

137
00:07:47,370 --> 00:07:51,030
‫then you see that it's working just like before.

138
00:07:51,030 --> 00:07:52,800
‫The only difference right now

139
00:07:52,800 --> 00:07:55,530
‫is that when we select a movie here

140
00:07:55,530 --> 00:07:59,970
‫and then we search for another one, let's say test,

141
00:07:59,970 --> 00:08:03,330
‫then this one here is not closed.

142
00:08:03,330 --> 00:08:06,870
‫And so that's because we are no longer calling

143
00:08:06,870 --> 00:08:07,803
‫handleCloseMovie.

144
00:08:08,700 --> 00:08:11,250
‫So what should we do about it?

145
00:08:11,250 --> 00:08:14,760
‫Well, we can just leave it as it is right now,

146
00:08:14,760 --> 00:08:18,330
‫so in order to make this really reusable,

147
00:08:18,330 --> 00:08:20,970
‫or we could also accept a callback function

148
00:08:20,970 --> 00:08:25,440
‫that the user of this custom hook can pass in if they want,

149
00:08:25,440 --> 00:08:28,470
‫and then we can call that at the very beginning.

150
00:08:28,470 --> 00:08:32,100
‫And so this is a way of customizing this custom hook

151
00:08:32,100 --> 00:08:33,540
‫a little bit more.

152
00:08:33,540 --> 00:08:35,760
‫So we can think of this argument here,

153
00:08:35,760 --> 00:08:39,900
‫again, a bit like the public API of this custom hook,

154
00:08:39,900 --> 00:08:42,150
‫so just like we can think of props

155
00:08:42,150 --> 00:08:45,720
‫as the custom API of a component.

156
00:08:45,720 --> 00:08:50,070
‫So a custom hook like this can also be created by someone

157
00:08:50,070 --> 00:08:52,740
‫and then consumed by someone else.

158
00:08:52,740 --> 00:08:56,610
‫And so that's the whole point of creating reusable pieces

159
00:08:56,610 --> 00:09:00,540
‫of stateful logic, okay?

160
00:09:00,540 --> 00:09:03,990
‫And so, well, let's remove that from here.

161
00:09:03,990 --> 00:09:05,910
‫And just to make this a bit more clear,

162
00:09:05,910 --> 00:09:10,353
‫we can call this at the very beginning of our effect.

163
00:09:11,670 --> 00:09:13,140
‫So we can say callback,

164
00:09:13,140 --> 00:09:16,560
‫and then we only want to call it if it actually exists.

165
00:09:16,560 --> 00:09:19,350
‫And so we can basically do optional chaining

166
00:09:19,350 --> 00:09:21,960
‫on calling a function as well.

167
00:09:21,960 --> 00:09:24,330
‫So that's just like this,

168
00:09:24,330 --> 00:09:27,720
‫or actually the other way around, so like this.

169
00:09:27,720 --> 00:09:30,240
‫And so now this function will only be called

170
00:09:30,240 --> 00:09:32,310
‫if it actually exists.

171
00:09:32,310 --> 00:09:34,530
‫So without this optional training part here,

172
00:09:34,530 --> 00:09:37,290
‫we would first have to check if it does exist,

173
00:09:37,290 --> 00:09:38,763
‫and then we would call it.

174
00:09:39,900 --> 00:09:41,970
‫So if we now try this again,

175
00:09:41,970 --> 00:09:44,280
‫since we didn't pass in any callback yet,

176
00:09:44,280 --> 00:09:46,383
‫this will then work without problems.

177
00:09:47,910 --> 00:09:50,520
‫So you see no problems there.

178
00:09:50,520 --> 00:09:54,000
‫But now we can actually pass in that callback,

179
00:09:54,000 --> 00:09:55,803
‫which is handleCloseMovie,

180
00:09:57,480 --> 00:10:00,000
‫and we can use this function here

181
00:10:00,000 --> 00:10:02,340
‫before it is actually defined.

182
00:10:02,340 --> 00:10:04,620
‫Because remember, that in JavaScript,

183
00:10:04,620 --> 00:10:07,860
‫function declarations like this are hoisted.

184
00:10:07,860 --> 00:10:09,660
‫And so that's one of the big reasons

185
00:10:09,660 --> 00:10:13,110
‫why I don't like to do this,

186
00:10:13,110 --> 00:10:15,183
‫what many people do these days,

187
00:10:16,770 --> 00:10:19,290
‫so writing an arrow function like this.

188
00:10:19,290 --> 00:10:23,430
‫So if I did this, then I couldn't do it like this.

189
00:10:23,430 --> 00:10:26,190
‫I would first have to create a function,

190
00:10:26,190 --> 00:10:28,380
‫but like this, that's not necessary,

191
00:10:28,380 --> 00:10:29,970
‫and so, one of the reasons

192
00:10:29,970 --> 00:10:32,703
‫why I always prefer function declarations.

193
00:10:33,990 --> 00:10:35,733
‫Okay, let's try this again.

194
00:10:37,350 --> 00:10:39,243
‫So let's open some movie,

195
00:10:41,310 --> 00:10:42,960
‫and beautiful!

196
00:10:42,960 --> 00:10:46,770
‫So now the currently open movie is immediately closed

197
00:10:46,770 --> 00:10:49,833
‫as the search query here changes.

198
00:10:50,970 --> 00:10:52,620
‫Great, so with this,

199
00:10:52,620 --> 00:10:56,460
‫we really cleaned up our app component here.

200
00:10:56,460 --> 00:10:59,910
‫So we only have this small effect here left,

201
00:10:59,910 --> 00:11:03,660
‫but we will actually also take care of that in the future.

202
00:11:03,660 --> 00:11:07,650
‫And now let's just quickly recap what we did here.

203
00:11:07,650 --> 00:11:11,850
‫So basically, we took all the logic that belongs together

204
00:11:11,850 --> 00:11:14,010
‫to search for movies

205
00:11:14,010 --> 00:11:17,790
‫and simply placed it here into this custom hook.

206
00:11:17,790 --> 00:11:22,740
‫And notice that we used four hooks to achieve that result,

207
00:11:22,740 --> 00:11:26,250
‫so one useEffect and three useStates.

208
00:11:26,250 --> 00:11:28,710
‫And that's important, because remember,

209
00:11:28,710 --> 00:11:33,300
‫a custom hook actually needs to use at least one React hook,

210
00:11:33,300 --> 00:11:37,710
‫otherwise, it's just irregular function, right?

211
00:11:37,710 --> 00:11:40,800
‫So we took all the logic that belongs together,

212
00:11:40,800 --> 00:11:43,650
‫packed it here into this one function,

213
00:11:43,650 --> 00:11:47,880
‫and then returned everything that is necessary for the app

214
00:11:47,880 --> 00:11:51,423
‫to keep working in exactly the same way as before.

215
00:11:52,590 --> 00:11:56,610
‫Now here we just need to probably also add the callback

216
00:11:56,610 --> 00:11:59,010
‫to the dependency array.

217
00:11:59,010 --> 00:12:04,010
‫But then you see we have this infinite reload here of error.

218
00:12:05,820 --> 00:12:10,020
‫Now, fixing this is too difficult for us at this point.

219
00:12:10,020 --> 00:12:12,300
‫So I actually didn't think of this,

220
00:12:12,300 --> 00:12:16,260
‫because I hadn't even prepared this lecture here before.

221
00:12:16,260 --> 00:12:18,990
‫So let's actually go back,

222
00:12:18,990 --> 00:12:21,180
‫remove that from the dependency array.

223
00:12:21,180 --> 00:12:23,610
‫But since we should really not lie

224
00:12:23,610 --> 00:12:26,070
‫about our dependencies in the array,

225
00:12:26,070 --> 00:12:30,450
‫let's then remove the entire ability to do this.

226
00:12:30,450 --> 00:12:32,670
‫So I will just comment this out,

227
00:12:32,670 --> 00:12:36,633
‫take away the callback, and here as well.

228
00:12:37,860 --> 00:12:39,870
‫So then the custom hook will not work

229
00:12:39,870 --> 00:12:42,390
‫exactly the way as it did before,

230
00:12:42,390 --> 00:12:44,340
‫but that's not a big deal here.

231
00:12:44,340 --> 00:12:45,960
‫So we are just learning,

232
00:12:45,960 --> 00:12:47,730
‫so we just wanted to learn

233
00:12:47,730 --> 00:12:52,730
‫how we can extract this non-visual logic into a custom hook

234
00:12:53,220 --> 00:12:54,780
‫like we just did.

235
00:12:54,780 --> 00:12:56,790
‫And to practice this a little bit more,

236
00:12:56,790 --> 00:12:59,913
‫we will do a few more in the next few lectures.

