﻿1
00:00:01,110 --> 00:00:04,170
‫Now that we know how to use the Context API

2
00:00:04,170 --> 00:00:05,400
‫in practice,

3
00:00:05,400 --> 00:00:07,800
‫we can take it to the next level

4
00:00:07,800 --> 00:00:11,070
‫and implement a custom Provider component

5
00:00:11,070 --> 00:00:15,033
‫as well as a custom hook to then consume the data.

6
00:00:16,710 --> 00:00:18,900
‫Now, I want to start by saying

7
00:00:18,900 --> 00:00:21,720
‫that the implementation that we have right now

8
00:00:21,720 --> 00:00:24,030
‫is actually perfectly fine.

9
00:00:24,030 --> 00:00:25,740
‫So it works great.

10
00:00:25,740 --> 00:00:29,670
‫And so in many applications, this is more than enough.

11
00:00:29,670 --> 00:00:32,880
‫However, as I said at the beginning of the lecture,

12
00:00:32,880 --> 00:00:35,370
‫we can now make this even more advanced

13
00:00:35,370 --> 00:00:38,700
‫by implementing some more advanced patterns.

14
00:00:38,700 --> 00:00:41,100
‫And so let's now do that.

15
00:00:41,100 --> 00:00:45,510
‫So the idea is basically to remove all the state

16
00:00:45,510 --> 00:00:49,530
‫and state updating logic, all from this component

17
00:00:49,530 --> 00:00:54,530
‫and place it into our own custom Context Provider component.

18
00:00:54,540 --> 00:00:56,820
‫So we will then have all the state

19
00:00:56,820 --> 00:00:59,040
‫and we will then provide that

20
00:00:59,040 --> 00:01:02,010
‫using context into our application.

21
00:01:02,010 --> 00:01:04,890
‫So it's basically just a refactoring

22
00:01:04,890 --> 00:01:06,540
‫of what we already have

23
00:01:06,540 --> 00:01:09,750
‫but the functionality will stay exactly the same

24
00:01:09,750 --> 00:01:12,480
‫and we still will have all three parts.

25
00:01:12,480 --> 00:01:15,630
‫So creating the context, then providing a value,

26
00:01:15,630 --> 00:01:17,070
‫and then reading it.

27
00:01:17,070 --> 00:01:20,973
‫We will just have these different parts in different files.

28
00:01:22,230 --> 00:01:25,320
‫Okay, so let's now start implementing that.

29
00:01:25,320 --> 00:01:30,060
‫And the first thing is to, once again, duplicating this file

30
00:01:30,060 --> 00:01:32,280
‫and then calling it version one

31
00:01:32,280 --> 00:01:34,953
‫so we can also keep the original version.

32
00:01:36,240 --> 00:01:37,290
‫Okay.

33
00:01:37,290 --> 00:01:40,620
‫And then next, let's create a new component

34
00:01:40,620 --> 00:01:45,273
‫called PostContext.js.

35
00:01:48,150 --> 00:01:49,680
‫Okay.

36
00:01:49,680 --> 00:01:50,513
‫And here,

37
00:01:50,513 --> 00:01:53,613
‫let's actually create this function manually ourselves.

38
00:01:54,480 --> 00:01:56,253
‫So PostContext,

39
00:01:57,540 --> 00:02:00,780
‫and we will then later also export it.

40
00:02:00,780 --> 00:02:05,580
‫And basically what we do now is to grab all this stuff,

41
00:02:05,580 --> 00:02:08,220
‫so everything that is related to the context,

42
00:02:08,220 --> 00:02:10,293
‫and place it into that other file.

43
00:02:11,580 --> 00:02:15,633
‫So let's cut that, place that here,

44
00:02:16,620 --> 00:02:19,920
‫and then we should probably import this.

45
00:02:19,920 --> 00:02:22,110
‫So one good way of doing that

46
00:02:22,110 --> 00:02:24,660
‫is to delete part of the string.

47
00:02:24,660 --> 00:02:27,180
‫And so then we get our auto complete back

48
00:02:27,180 --> 00:02:28,980
‫where we just have to hit Enter,

49
00:02:28,980 --> 00:02:32,520
‫and then that gets automatically imported.

50
00:02:32,520 --> 00:02:35,070
‫Now here, not sure why we're getting this error.

51
00:02:35,070 --> 00:02:36,840
‫Ah, and it's just because

52
00:02:36,840 --> 00:02:39,540
‫we of course now already have this variable

53
00:02:39,540 --> 00:02:41,370
‫called PostContext.

54
00:02:41,370 --> 00:02:45,390
‫And so actually I want this not to be called PostContext

55
00:02:45,390 --> 00:02:46,440
‫but the PostProvider.

56
00:02:49,680 --> 00:02:52,890
‫So this then makes the intention of this component

57
00:02:52,890 --> 00:02:54,300
‫a bit more clear.

58
00:02:54,300 --> 00:02:55,860
‫So basically from here,

59
00:02:55,860 --> 00:02:59,670
‫we will export or we will return a provider.

60
00:02:59,670 --> 00:03:02,347
‫So that's why we call this the PostProvider.

61
00:03:03,597 --> 00:03:04,650
‫All right?

62
00:03:04,650 --> 00:03:07,380
‫And now let's grip all the state

63
00:03:07,380 --> 00:03:09,633
‫and the state updating logic from here.

64
00:03:10,770 --> 00:03:13,953
‫So all of this, but of course not this effect.

65
00:03:14,880 --> 00:03:16,743
‫And then let's place that here.

66
00:03:17,850 --> 00:03:21,723
‫And then we are again, missing some stuff here.

67
00:03:23,670 --> 00:03:26,493
‫So let's use that trick again to import useState.

68
00:03:27,450 --> 00:03:31,080
‫And then we need to also copy this function right here.

69
00:03:31,080 --> 00:03:32,520
‫And here we cannot cut it

70
00:03:32,520 --> 00:03:35,970
‫because we actually need it in another function.

71
00:03:35,970 --> 00:03:40,970
‫So let's just copy it and place that here,

72
00:03:41,100 --> 00:03:44,760
‫and then we also need to copy this.

73
00:03:44,760 --> 00:03:47,520
‫So probably we should export all of this here

74
00:03:47,520 --> 00:03:50,640
‫into some other special file

75
00:03:50,640 --> 00:03:53,043
‫but here we just want to keep it very simple.

76
00:03:55,295 --> 00:03:56,128
‫Okay.

77
00:03:56,128 --> 00:03:59,190
‫Well, actually we also removed this state,

78
00:03:59,190 --> 00:04:01,983
‫so about the dark mode.

79
00:04:02,940 --> 00:04:07,940
‫So let's place that back right here,

80
00:04:10,350 --> 00:04:15,350
‫and then what we want is to also grab this.

81
00:04:15,420 --> 00:04:18,603
‫So cut it and remove this one here as well.

82
00:04:20,850 --> 00:04:25,850
‫All right, so again, we are just refactoring everything here

83
00:04:25,890 --> 00:04:28,680
‫into this provider

84
00:04:28,680 --> 00:04:32,640
‫so this component will just be another React component

85
00:04:32,640 --> 00:04:35,343
‫and so it needs to return some JSX.

86
00:04:36,450 --> 00:04:40,443
‫And so that JSX will be this provider.

87
00:04:41,610 --> 00:04:43,140
‫Let's close it,

88
00:04:43,140 --> 00:04:45,420
‫and for now, we are good like this.

89
00:04:45,420 --> 00:04:49,533
‫And so here, I think we now removed all our errors.

90
00:04:50,580 --> 00:04:53,070
‫Now we have some problems right here

91
00:04:53,070 --> 00:04:56,400
‫where we now are trying to read from the PostContext

92
00:04:56,400 --> 00:04:58,230
‫which no longer exists,

93
00:04:58,230 --> 00:05:00,363
‫but let's take care of that later.

94
00:05:01,920 --> 00:05:04,440
‫So what we want to do now

95
00:05:04,440 --> 00:05:06,930
‫is to use that PostProvider here

96
00:05:06,930 --> 00:05:10,770
‫exactly in the same way that we used the provider before.

97
00:05:10,770 --> 00:05:12,843
‫So exactly what we had here earlier.

98
00:05:13,770 --> 00:05:17,253
‫So let's actually for now export this from here.

99
00:05:21,904 --> 00:05:25,654
‫So PostProvider to an export default for now.

100
00:05:29,460 --> 00:05:34,460
‫And so then here we are able to just import PostProvider

101
00:05:36,480 --> 00:05:37,313
‫like this.

102
00:05:40,380 --> 00:05:41,403
‫All right.

103
00:05:43,320 --> 00:05:44,670
‫Place that here.

104
00:05:44,670 --> 00:05:47,340
‫But that will actually still not work

105
00:05:47,340 --> 00:05:50,310
‫because watch what's happening right now.

106
00:05:50,310 --> 00:05:53,220
‫So we are passing all of these children here

107
00:05:53,220 --> 00:05:56,790
‫into the PostProvider component, right?

108
00:05:56,790 --> 00:05:58,890
‫But then all that we do here

109
00:05:58,890 --> 00:06:02,840
‫is to return this PostContext.Provider

110
00:06:04,260 --> 00:06:07,110
‫but we're not doing anything with the children.

111
00:06:07,110 --> 00:06:11,010
‫And let me demonstrate that here in the application.

112
00:06:11,010 --> 00:06:12,570
‫But before we do that,

113
00:06:12,570 --> 00:06:16,530
‫we actually need to now export this PostContext

114
00:06:16,530 --> 00:06:18,843
‫so that we can use it here in App.

115
00:06:21,540 --> 00:06:24,960
‫So let's now instead of the default export,

116
00:06:24,960 --> 00:06:26,790
‫export him like this.

117
00:06:26,790 --> 00:06:28,503
‫So a named export.

118
00:06:30,270 --> 00:06:31,173
‫So PostContext,

119
00:06:34,200 --> 00:06:39,200
‫and so let's now here import this as name imports as well.

120
00:06:39,570 --> 00:06:42,483
‫So exactly in the same way as we exported them.

121
00:06:43,500 --> 00:06:47,790
‫So PostContext, and beautiful.

122
00:06:47,790 --> 00:06:50,280
‫So that basically fixes it

123
00:06:50,280 --> 00:06:52,740
‫even though now as I mentioned before,

124
00:06:52,740 --> 00:06:54,600
‫we have an empty page.

125
00:06:54,600 --> 00:06:56,160
‫And so the reason for that

126
00:06:56,160 --> 00:06:58,350
‫is that all we are doing now

127
00:06:58,350 --> 00:07:03,350
‫is to return this Context Provider, right?

128
00:07:03,390 --> 00:07:04,680
‫So again,

129
00:07:04,680 --> 00:07:08,160
‫right here we have the PostProvider component,

130
00:07:08,160 --> 00:07:13,160
‫but all this does is to return this PostContext.Provider.

131
00:07:14,220 --> 00:07:16,920
‫And so then that's what we see in our tree.

132
00:07:16,920 --> 00:07:19,050
‫And so what we need to do now

133
00:07:19,050 --> 00:07:22,023
‫is to accept the children prop like this

134
00:07:24,990 --> 00:07:28,143
‫and then place the children back here.

135
00:07:30,450 --> 00:07:33,843
‫And with that, then our application works again.

136
00:07:34,680 --> 00:07:38,970
‫Let's go back to normal mode and let's try to search.

137
00:07:38,970 --> 00:07:40,170
‫And yeah,

138
00:07:40,170 --> 00:07:42,180
‫so everything works the same

139
00:07:42,180 --> 00:07:44,250
‫but now we created ourselves

140
00:07:44,250 --> 00:07:47,610
‫our own custom Context Provider component,

141
00:07:47,610 --> 00:07:49,773
‫which is this PostProvider.

142
00:07:51,930 --> 00:07:52,770
‫All right?

143
00:07:52,770 --> 00:07:53,603
‫And with this,

144
00:07:53,603 --> 00:07:57,810
‫we really cleaned up tremendously this App file,

145
00:07:57,810 --> 00:08:00,060
‫so our parent component.

146
00:08:00,060 --> 00:08:03,310
‫And here actually we can make this even a bit cleaner

147
00:08:04,200 --> 00:08:08,070
‫because this section here in this button

148
00:08:08,070 --> 00:08:11,310
‫of course don't need this provider.

149
00:08:11,310 --> 00:08:13,983
‫And so with this, I think it looks even a bit better.

150
00:08:14,940 --> 00:08:18,900
‫So it's important that you understand what we just did here.

151
00:08:18,900 --> 00:08:22,170
‫So we created this PostProvider component

152
00:08:22,170 --> 00:08:25,770
‫which we now wrap around all our other components,

153
00:08:25,770 --> 00:08:28,950
‫and you can always compare that with the V1 file

154
00:08:28,950 --> 00:08:30,930
‫that we created earlier.

155
00:08:30,930 --> 00:08:35,040
‫So we pass this here into the opening and the closing tag

156
00:08:35,040 --> 00:08:36,030
‫and so, therefore,

157
00:08:36,030 --> 00:08:39,360
‫these will become the children of this component.

158
00:08:39,360 --> 00:08:42,210
‫So then we use the children prop here

159
00:08:42,210 --> 00:08:44,520
‫and then we wrap all these children

160
00:08:44,520 --> 00:08:48,567
‫inside the PostContext Provider just like we had before.

161
00:08:48,567 --> 00:08:50,100
‫And so by doing that,

162
00:08:50,100 --> 00:08:54,090
‫we could place all the state and the state update logic

163
00:08:54,090 --> 00:08:57,090
‫into its own separate context file,

164
00:08:57,090 --> 00:08:59,400
‫which then cleaned up tremendously

165
00:08:59,400 --> 00:09:02,010
‫our main component that we have here.

166
00:09:02,010 --> 00:09:03,810
‫So this app component.

167
00:09:03,810 --> 00:09:06,810
‫And we could even do the same thing here

168
00:09:06,810 --> 00:09:10,533
‫with this fake dark mode, but let's keep it simple here.

169
00:09:11,850 --> 00:09:16,140
‫So here we could remove that from here, this comment,

170
00:09:16,140 --> 00:09:17,583
‫and place that here,

171
00:09:18,420 --> 00:09:20,583
‫but that's not really important.

172
00:09:22,080 --> 00:09:25,530
‫So with this, we finished the first part of the lecture

173
00:09:25,530 --> 00:09:29,130
‫which was to create the Context Provider component.

174
00:09:29,130 --> 00:09:31,530
‫But now remember how I told you

175
00:09:31,530 --> 00:09:35,370
‫that we are also going to create our own custom hook?

176
00:09:35,370 --> 00:09:37,773
‫And so let's see what that means.

177
00:09:39,120 --> 00:09:41,430
‫So right now to consume the context,

178
00:09:41,430 --> 00:09:44,670
‫we are always using this usecontext hook

179
00:09:44,670 --> 00:09:48,360
‫and then we pass in the PostContext object.

180
00:09:48,360 --> 00:09:50,460
‫And this works great,

181
00:09:50,460 --> 00:09:53,940
‫but over time after using this many, many times,

182
00:09:53,940 --> 00:09:57,030
‫you will notice that it can become a bit annoying

183
00:09:57,030 --> 00:10:00,810
‫to always have to write this PostContext here.

184
00:10:00,810 --> 00:10:02,940
‫So basically this part here

185
00:10:02,940 --> 00:10:06,300
‫is always repeated over and over again

186
00:10:06,300 --> 00:10:08,550
‫in all the components

187
00:10:08,550 --> 00:10:12,060
‫where we actually read the value from the context.

188
00:10:12,060 --> 00:10:15,090
‫And so basically we can encapsulate this part

189
00:10:15,090 --> 00:10:17,313
‫into its own custom hook.

190
00:10:18,600 --> 00:10:21,270
‫So let's come back here into this file

191
00:10:21,270 --> 00:10:24,120
‫and then create it right here as well.

192
00:10:24,120 --> 00:10:26,190
‫So that's a very common pattern

193
00:10:26,190 --> 00:10:28,950
‫that many developers use these days.

194
00:10:28,950 --> 00:10:32,610
‫So basically placing this Context Provider component

195
00:10:32,610 --> 00:10:36,753
‫and then the corresponding hook all into the same file.

196
00:10:38,700 --> 00:10:43,023
‫So let's call this one here, usePosts,

197
00:10:44,040 --> 00:10:46,203
‫and we don't need any argument then.

198
00:10:48,720 --> 00:10:52,740
‫And so here, let's then get the value out of the context,

199
00:10:52,740 --> 00:10:55,740
‫so the entire value which we will then return

200
00:10:55,740 --> 00:10:58,980
‫so that in our components we can destructure it.

201
00:10:58,980 --> 00:11:03,453
‫And so now we will use the useContext hook right here.

202
00:11:04,680 --> 00:11:09,330
‫So using it here and then passing in the PostContext

203
00:11:09,330 --> 00:11:11,370
‫just like we did before.

204
00:11:11,370 --> 00:11:16,370
‫And now we can return the context like this,

205
00:11:16,827 --> 00:11:20,490
‫and then instead of returning this context here,

206
00:11:20,490 --> 00:11:23,610
‫we can leave it encapsulated inside this file

207
00:11:23,610 --> 00:11:26,670
‫and instead export this custom hook.

208
00:11:26,670 --> 00:11:30,540
‫So with this, we then basically create like an API

209
00:11:30,540 --> 00:11:31,863
‫for this context.

210
00:11:33,840 --> 00:11:37,560
‫So again, instead of exposing the context object itself,

211
00:11:37,560 --> 00:11:39,210
‫we just expose a function

212
00:11:39,210 --> 00:11:42,570
‫with which we can then access that.

213
00:11:42,570 --> 00:11:43,500
‫Okay?

214
00:11:43,500 --> 00:11:46,860
‫So this one is nicely called usePosts.

215
00:11:46,860 --> 00:11:51,860
‫And so let's use that here instead of the PostContext.

216
00:11:54,300 --> 00:11:59,300
‫So usePosts, and now we just everywhere replace this.

217
00:12:03,570 --> 00:12:07,470
‫So I will now use Command or Control + D,

218
00:12:07,470 --> 00:12:09,870
‫which again is this one here.

219
00:12:09,870 --> 00:12:14,870
‫So add next occurrence to select all of them.

220
00:12:16,480 --> 00:12:20,430
‫And so then we just use usePosts,

221
00:12:20,430 --> 00:12:22,470
‫and beautiful.

222
00:12:22,470 --> 00:12:24,030
‫So it works again.

223
00:12:24,030 --> 00:12:27,390
‫And if you ask me, this is now a lot cleaner.

224
00:12:27,390 --> 00:12:28,680
‫So we don't have to think

225
00:12:28,680 --> 00:12:30,840
‫about the name of the context anymore,

226
00:12:30,840 --> 00:12:33,000
‫we just write usePosts

227
00:12:33,000 --> 00:12:35,763
‫and then we get whatever we want from there.

228
00:12:37,600 --> 00:12:38,640
‫Okay.

229
00:12:38,640 --> 00:12:41,160
‫Now let me just show you something

230
00:12:41,160 --> 00:12:42,153
‫which is,

231
00:12:43,140 --> 00:12:46,323
‫for example, trying to use that custom hook right here.

232
00:12:48,900 --> 00:12:52,320
‫So usePosts right here

233
00:12:52,320 --> 00:12:54,810
‫and then let's log that to the console.

234
00:12:54,810 --> 00:12:56,760
‫So what do you think is going to happen?

235
00:12:56,760 --> 00:12:58,893
‫What do you think this x will be?

236
00:13:00,060 --> 00:13:02,580
‫Well, it is undefined.

237
00:13:02,580 --> 00:13:04,470
‫So why do you think that is?

238
00:13:04,470 --> 00:13:08,730
‫Why is the context value suddenly undefined?

239
00:13:08,730 --> 00:13:12,783
‫Well, all we need to do is to look at our componentry.

240
00:13:14,910 --> 00:13:19,910
‫So we tried to use the context here inside of App

241
00:13:20,010 --> 00:13:22,560
‫but the context only provides the value

242
00:13:22,560 --> 00:13:25,140
‫to all its children components.

243
00:13:25,140 --> 00:13:29,460
‫So only to all of these that are below the provider.

244
00:13:29,460 --> 00:13:32,550
‫So basically only to these ones right here

245
00:13:32,550 --> 00:13:34,440
‫and to ones that are inside it,

246
00:13:34,440 --> 00:13:36,600
‫but not right here.

247
00:13:36,600 --> 00:13:37,920
‫And so this could lead

248
00:13:37,920 --> 00:13:41,880
‫to some hard-to-find bugs in a larger application.

249
00:13:41,880 --> 00:13:45,270
‫And so let's now do something against this.

250
00:13:45,270 --> 00:13:49,050
‫So basically to prevent someone from using this hook,

251
00:13:49,050 --> 00:13:52,503
‫so to accessing the context value where they shouldn't.

252
00:13:53,640 --> 00:13:56,940
‫So notice how the context value was undefined.

253
00:13:56,940 --> 00:14:00,780
‫And so what we can do is to test for that.

254
00:14:00,780 --> 00:14:05,193
‫So we can check if the context is undefined

255
00:14:06,990 --> 00:14:09,813
‫then let's just throw a new error.

256
00:14:14,370 --> 00:14:16,710
‫And then let's let the developer know

257
00:14:16,710 --> 00:14:21,710
‫that PostContext was used outside of the PostProvider.

258
00:14:27,540 --> 00:14:30,120
‫And yeah, there we go.

259
00:14:30,120 --> 00:14:32,580
‫So this is actually a lot better

260
00:14:32,580 --> 00:14:35,862
‫even though normally we don't like errors,

261
00:14:35,862 --> 00:14:37,620
‫(chuckles) but in a situation like this,

262
00:14:37,620 --> 00:14:42,060
‫it's actually a lot better to have directly an error here

263
00:14:42,060 --> 00:14:44,640
‫than maybe having the developer think

264
00:14:44,640 --> 00:14:46,470
‫that this somehow works.

265
00:14:46,470 --> 00:14:47,303
‫So with this,

266
00:14:47,303 --> 00:14:50,133
‫they know immediately that this cannot work.

267
00:14:51,630 --> 00:14:54,900
‫So that's why we should always create an error

268
00:14:54,900 --> 00:14:59,160
‫in the situation where we are trying to access the context

269
00:14:59,160 --> 00:15:00,543
‫where we actually cannot.

270
00:15:01,740 --> 00:15:02,580
‫Okay.

271
00:15:02,580 --> 00:15:04,770
‫And this is all I wanted to show you

272
00:15:04,770 --> 00:15:07,020
‫for this advanced pattern.

273
00:15:07,020 --> 00:15:11,160
‫So again, it is composed of two parts basically.

274
00:15:11,160 --> 00:15:12,870
‫First, the PostProvider

275
00:15:12,870 --> 00:15:15,150
‫and then our own custom hooks

276
00:15:15,150 --> 00:15:18,330
‫to read the value out of the context.

277
00:15:18,330 --> 00:15:19,740
‫And I'm showing this to you

278
00:15:19,740 --> 00:15:22,410
‫because this is basically like a recipe

279
00:15:22,410 --> 00:15:25,890
‫that you can always follow in all your own projects

280
00:15:25,890 --> 00:15:28,800
‫when you want to use the Context API.

281
00:15:28,800 --> 00:15:32,190
‫So we always do this in the exact same way.

282
00:15:32,190 --> 00:15:33,600
‫So we create a context,

283
00:15:33,600 --> 00:15:36,960
‫then we create our own Provider component

284
00:15:36,960 --> 00:15:39,150
‫which receives to the children

285
00:15:39,150 --> 00:15:42,070
‫so that we can then use it like this here

286
00:15:43,170 --> 00:15:45,213
‫and then we pass the value in there,

287
00:15:46,260 --> 00:15:49,140
‫and then of course, also return the children here.

288
00:15:49,140 --> 00:15:52,740
‫And then in the end, we always have this own custom hook.

289
00:15:52,740 --> 00:15:54,660
‫So again, always the same recipe

290
00:15:54,660 --> 00:15:58,050
‫that you can start using in your own applications.

291
00:15:58,050 --> 00:15:59,010
‫Great.

292
00:15:59,010 --> 00:16:00,900
‫So now we know really well

293
00:16:00,900 --> 00:16:04,080
‫how to use the Context API in practice.

294
00:16:04,080 --> 00:16:05,610
‫And so let's now go back

295
00:16:05,610 --> 00:16:07,440
‫to talking a little bit more

296
00:16:07,440 --> 00:16:09,180
‫about state management

297
00:16:09,180 --> 00:16:12,693
‫and how the Context API fits into that picture.

