﻿1
00:00:01,140 --> 00:00:03,510
‫Let's now learn about React Router's

2
00:00:03,510 --> 00:00:06,540
‫powerful new data loading feature,

3
00:00:06,540 --> 00:00:08,673
‫which is called loaders.

4
00:00:10,110 --> 00:00:14,670
‫So the idea behind a loader is that somewhere in our code

5
00:00:14,670 --> 00:00:19,670
‫we create a function that fetches some data from an API.

6
00:00:19,680 --> 00:00:24,300
‫We then provide that loader function to one of our routes

7
00:00:24,300 --> 00:00:27,510
‫and that route will then fetch that data

8
00:00:27,510 --> 00:00:31,350
‫as soon as the application goes to that route.

9
00:00:31,350 --> 00:00:34,890
‫And then in the end, once the data has arrived,

10
00:00:34,890 --> 00:00:36,150
‫it will be provided

11
00:00:36,150 --> 00:00:40,590
‫to the page component itself using a custom hook.

12
00:00:40,590 --> 00:00:42,810
‫So that sounds a bit confusing.

13
00:00:42,810 --> 00:00:46,590
‫And so let's actually implement this with code.

14
00:00:46,590 --> 00:00:51,300
‫And I want to start by fetching the menu data.

15
00:00:51,300 --> 00:00:54,420
‫So again, we do this in three steps.

16
00:00:54,420 --> 00:00:56,100
‫First, we create a loader.

17
00:00:56,100 --> 00:00:58,950
‫Second, we provide the loader, and third,

18
00:00:58,950 --> 00:01:02,370
‫we provide the data to the page.

19
00:01:02,370 --> 00:01:05,850
‫Now, this data loader can be placed anywhere

20
00:01:05,850 --> 00:01:07,230
‫in our code base

21
00:01:07,230 --> 00:01:10,890
‫but the convention seems to be to place the loader

22
00:01:10,890 --> 00:01:15,890
‫for the data of a certain page inside the file of that page.

23
00:01:16,860 --> 00:01:21,120
‫So here in this case, we want to load the menu data.

24
00:01:21,120 --> 00:01:23,640
‫And so let's go to this component

25
00:01:23,640 --> 00:01:26,253
‫and create the loader function right here.

26
00:01:29,760 --> 00:01:33,000
‫So again, the convention here

27
00:01:33,000 --> 00:01:35,823
‫is to just call this function a loader.

28
00:01:37,020 --> 00:01:40,290
‫And so then here, this function needs to fetch the data

29
00:01:40,290 --> 00:01:42,390
‫and then return it.

30
00:01:42,390 --> 00:01:45,963
‫Now, where are we actually going to get that data from?

31
00:01:46,860 --> 00:01:49,800
‫Well, that's where the restaurant service

32
00:01:49,800 --> 00:01:51,900
‫now comes into play.

33
00:01:51,900 --> 00:01:54,000
‫So let's open up this file.

34
00:01:54,000 --> 00:01:56,970
‫And you see that here we have multiple functions.

35
00:01:56,970 --> 00:02:01,683
‫So we have getMenu, we have getOrder based on an ID,

36
00:02:02,610 --> 00:02:06,330
‫we have createOrder, and we have updateOrder.

37
00:02:06,330 --> 00:02:10,260
‫So if you want, you can take a look at all of this code

38
00:02:10,260 --> 00:02:13,920
‫but this is just some pretty standard code here.

39
00:02:13,920 --> 00:02:18,870
‫What matters is that this is the API URL, which again

40
00:02:18,870 --> 00:02:23,870
‫is that API that the React Fast Pizza Company already has.

41
00:02:24,780 --> 00:02:28,530
‫So it is here in this URL, and it might change

42
00:02:28,530 --> 00:02:30,570
‫by the time you're watching this video.

43
00:02:30,570 --> 00:02:33,093
‫But then I will just update this file.

44
00:02:33,990 --> 00:02:38,990
‫So just to see the data, let's grab that URL, go here

45
00:02:39,180 --> 00:02:41,163
‫and then /menu.

46
00:02:42,120 --> 00:02:44,370
‫And so then that should load.

47
00:02:44,370 --> 00:02:49,370
‫And indeed, here is all the data for our menu.

48
00:02:49,380 --> 00:02:53,340
‫So here that's this /menu right there.

49
00:02:53,340 --> 00:02:55,230
‫And so all we need to do now

50
00:02:55,230 --> 00:02:59,823
‫in that loader is to call this getMenu function.

51
00:03:01,170 --> 00:03:02,790
‫All right, so basically,

52
00:03:02,790 --> 00:03:05,370
‫we abstracted this function right here

53
00:03:05,370 --> 00:03:06,600
‫into the service

54
00:03:06,600 --> 00:03:10,230
‫so that now we can use it inside our loader functions.

55
00:03:10,230 --> 00:03:12,360
‫And of course, we could also place

56
00:03:12,360 --> 00:03:16,260
‫all this logic right there in the loader as well.

57
00:03:16,260 --> 00:03:18,900
‫But it's a lot better to have this kind

58
00:03:18,900 --> 00:03:21,990
‫of logic here in a central place also

59
00:03:21,990 --> 00:03:25,890
‫because this might be necessary in some different places.

60
00:03:25,890 --> 00:03:30,890
‫And also because then we centralize also the API_URL.

61
00:03:31,350 --> 00:03:34,980
‫So it's nice to abstract this logic away here.

62
00:03:34,980 --> 00:03:36,480
‫So into that service.

63
00:03:36,480 --> 00:03:40,533
‫And then here, all we need to do is to call that function.

64
00:03:41,580 --> 00:03:45,693
‫So let's then save the result into a variable called menu.

65
00:03:47,070 --> 00:03:50,770
‫And then here we await calling getMenu.

66
00:03:52,290 --> 00:03:55,680
‫So this is then an async function

67
00:03:55,680 --> 00:03:58,470
‫that we also need to export.

68
00:03:58,470 --> 00:04:02,070
‫And so now here we have the default export

69
00:04:02,070 --> 00:04:03,780
‫for the component itself,

70
00:04:03,780 --> 00:04:06,390
‫and then we also have a named export

71
00:04:06,390 --> 00:04:08,280
‫for the loader function.

72
00:04:08,280 --> 00:04:10,710
‫But that's no problem at all.

73
00:04:10,710 --> 00:04:15,710
‫And now all we need to do is to return the menu.

74
00:04:16,170 --> 00:04:19,620
‫And we could have done this all in one line, but like this,

75
00:04:19,620 --> 00:04:21,480
‫it's a bit more explicit.

76
00:04:21,480 --> 00:04:23,640
‫So the loader function needs to return

77
00:04:23,640 --> 00:04:26,973
‫whatever data it wants to provide to the page.

78
00:04:28,410 --> 00:04:31,650
‫Okay, and now let's do the second step,

79
00:04:31,650 --> 00:04:35,313
‫which is to connect the loader function to the route.

80
00:04:36,240 --> 00:04:38,670
‫And so that function,

81
00:04:38,670 --> 00:04:41,163
‫so that loader is here in this component.

82
00:04:42,060 --> 00:04:45,843
‫And so in order to import now the named export,

83
00:04:46,860 --> 00:04:50,160
‫we do it like this, and then let's actually rename it

84
00:04:50,160 --> 00:04:52,770
‫because otherwise, we will later end up

85
00:04:52,770 --> 00:04:55,170
‫with multiple loaders.

86
00:04:55,170 --> 00:05:00,170
‫So let's say loader as menuLoader.

87
00:05:00,810 --> 00:05:04,290
‫So this is how we rename some named exports

88
00:05:04,290 --> 00:05:07,260
‫or named imports here in this case.

89
00:05:07,260 --> 00:05:12,260
‫And so here we can now specify the loader property

90
00:05:13,590 --> 00:05:16,670
‫and then specify the menuLoader.

91
00:05:17,910 --> 00:05:20,070
‫Okay, give it a save.

92
00:05:20,070 --> 00:05:23,310
‫And so with this, we completed step number two.

93
00:05:23,310 --> 00:05:27,450
‫So we now provided this loader function to the menu route.

94
00:05:27,450 --> 00:05:31,020
‫And now all we have to do is to get that data

95
00:05:31,020 --> 00:05:32,970
‫into the component.

96
00:05:32,970 --> 00:05:35,790
‫And so as I mentioned earlier, for that,

97
00:05:35,790 --> 00:05:39,600
‫we can use a custom hook, which is called useLoaderData.

98
00:05:41,970 --> 00:05:45,780
‫And here we don't have to pass in anything into the function

99
00:05:45,780 --> 00:05:49,410
‫because React Router will, of course, automatically know

100
00:05:49,410 --> 00:05:52,020
‫that the data that we want here is the one

101
00:05:52,020 --> 00:05:55,020
‫that is associated to this page.

102
00:05:55,020 --> 00:05:59,193
‫And so that's the data coming from this exact loader here.

103
00:06:01,920 --> 00:06:04,233
‫So let's then call it menu.

104
00:06:05,070 --> 00:06:09,510
‫And for now just log it to the console.

105
00:06:09,510 --> 00:06:11,310
‫So let's give it a save.

106
00:06:11,310 --> 00:06:15,483
‫Let's open up here actually our network tools.

107
00:06:16,470 --> 00:06:17,860
‫So this is pretty small

108
00:06:19,290 --> 00:06:21,633
‫but I can't make it too big as well.

109
00:06:22,710 --> 00:06:27,710
‫But yeah, so let's just reload here just to make sure.

110
00:06:27,870 --> 00:06:29,760
‫Then I will clear everything.

111
00:06:29,760 --> 00:06:33,033
‫And then let's move to the menu by clicking here.

112
00:06:35,010 --> 00:06:36,570
‫And indeed, you see

113
00:06:36,570 --> 00:06:41,430
‫that a new fetch request was fired off automatically.

114
00:06:41,430 --> 00:06:44,250
‫And if we then check out our console,

115
00:06:44,250 --> 00:06:48,510
‫then indeed, here we have our menu data.

116
00:06:48,510 --> 00:06:51,270
‫Beautiful. So this worked.

117
00:06:51,270 --> 00:06:55,470
‫And so we successfully connected this loader function now

118
00:06:55,470 --> 00:06:56,970
‫to this page.

119
00:06:56,970 --> 00:07:01,500
‫And effectively what we just did here was to implement

120
00:07:01,500 --> 00:07:05,550
‫or to use a render as you fetch strategy

121
00:07:05,550 --> 00:07:07,680
‫because the nice thing about this

122
00:07:07,680 --> 00:07:11,760
‫is that React Router will actually start fetching the data

123
00:07:11,760 --> 00:07:16,110
‫at the same time as it starts rendering the correct route.

124
00:07:16,110 --> 00:07:19,290
‫So these things really happen at the same time,

125
00:07:19,290 --> 00:07:24,030
‫while what we did before using useEffect was always a fetch

126
00:07:24,030 --> 00:07:25,980
‫on render approach.

127
00:07:25,980 --> 00:07:29,130
‫So basically, we rendered the component first,

128
00:07:29,130 --> 00:07:32,310
‫and then after the component was already rendered

129
00:07:32,310 --> 00:07:35,610
‫is when we then would start to fetch the data.

130
00:07:35,610 --> 00:07:37,200
‫And so that would then create

131
00:07:37,200 --> 00:07:41,520
‫so-called data loading waterfalls, but not here.

132
00:07:41,520 --> 00:07:45,030
‫So here everything really happens at the same time,

133
00:07:45,030 --> 00:07:47,730
‫which is a really nice

134
00:07:47,730 --> 00:07:50,523
‫and really modern thing to do as well.

135
00:07:51,480 --> 00:07:53,970
‫So with this, what we just did,

136
00:07:53,970 --> 00:07:57,390
‫React Router is no longer only responsible

137
00:07:57,390 --> 00:08:01,230
‫for matching component to URLs in the browser

138
00:08:01,230 --> 00:08:04,620
‫but to also provide the data that is necessary

139
00:08:04,620 --> 00:08:06,540
‫for each page.

140
00:08:06,540 --> 00:08:10,560
‫So again, in this case, for providing the menu data

141
00:08:10,560 --> 00:08:14,850
‫using the menuLoader to the menu page here.

142
00:08:14,850 --> 00:08:19,200
‫And this is really useful because URLs pages

143
00:08:19,200 --> 00:08:21,810
‫and the data that pages require

144
00:08:21,810 --> 00:08:24,990
‫are very often tightly coupled together.

145
00:08:24,990 --> 00:08:27,540
‫And so it is really practical

146
00:08:27,540 --> 00:08:30,570
‫in these situations to get both the page

147
00:08:30,570 --> 00:08:33,480
‫and the data all in one place.

148
00:08:33,480 --> 00:08:37,323
‫So all nicely integrated within React Router.

149
00:08:38,280 --> 00:08:41,760
‫But anyway, now that we know how this works,

150
00:08:41,760 --> 00:08:45,483
‫let's then actually do something with the menu here.

151
00:08:48,090 --> 00:08:53,090
‫So let's create one ul where we then loop over the menu.

152
00:08:54,750 --> 00:08:56,850
‫So .map.

153
00:08:56,850 --> 00:09:00,720
‫And then here, each item of the array is a pizza.

154
00:09:00,720 --> 00:09:05,133
‫And for each pizza, we want to render this menu item here.

155
00:09:06,300 --> 00:09:08,643
‫So here I see we have another error.

156
00:09:09,690 --> 00:09:14,310
‫So let's just automatically import that here.

157
00:09:14,310 --> 00:09:17,220
‫And then here, notice how this menu item,

158
00:09:17,220 --> 00:09:20,700
‫all it does is to receive one pizza object.

159
00:09:20,700 --> 00:09:23,190
‫So that's basically one of these objects

160
00:09:23,190 --> 00:09:24,993
‫that we have here in the menu.

161
00:09:27,180 --> 00:09:28,503
‫So MenuItem.

162
00:09:31,445 --> 00:09:34,317
‫And here we pass in the current pizza

163
00:09:35,340 --> 00:09:38,343
‫and the ID or actually the key.

164
00:09:39,210 --> 00:09:43,020
‫So never forget the key in a map like this.

165
00:09:43,020 --> 00:09:46,053
‫And so here, let's use pizza.id.

166
00:09:48,690 --> 00:09:51,090
‫All right, give it a save.

167
00:09:51,090 --> 00:09:53,943
‫And it is actually already working.

168
00:09:55,410 --> 00:09:57,150
‫So again, there's no styling.

169
00:09:57,150 --> 00:10:02,013
‫But here we have our menu with all these beautiful images.

170
00:10:02,910 --> 00:10:07,910
‫And yeah, again, this data is coming from React Router

171
00:10:09,450 --> 00:10:11,490
‫or at least it is being injected

172
00:10:11,490 --> 00:10:14,640
‫into this page using React Router.

173
00:10:14,640 --> 00:10:16,260
‫Now, you could, of course, argue

174
00:10:16,260 --> 00:10:19,770
‫that this is no different from what we have doing before.

175
00:10:19,770 --> 00:10:22,290
‫So we still have this function here

176
00:10:22,290 --> 00:10:24,360
‫right inside the component file.

177
00:10:24,360 --> 00:10:26,310
‫And so this might look very similar

178
00:10:26,310 --> 00:10:30,480
‫to simply fetching the data right in the component.

179
00:10:30,480 --> 00:10:34,140
‫So basically, just doing that data fetching here

180
00:10:34,140 --> 00:10:38,220
‫right inside a useEffect here in the component.

181
00:10:38,220 --> 00:10:40,560
‫However, as I mentioned earlier,

182
00:10:40,560 --> 00:10:44,670
‫this is actually using the render as you fetch strategy,

183
00:10:44,670 --> 00:10:49,020
‫so not the fetch on render that creates waterfalls.

184
00:10:49,020 --> 00:10:51,570
‫Also, as I mentioned in the beginning,

185
00:10:51,570 --> 00:10:55,380
‫this function here really could be placed anywhere

186
00:10:55,380 --> 00:10:56,700
‫because what matters

187
00:10:56,700 --> 00:11:01,230
‫is that the data fetching logic is actually centralized here

188
00:11:01,230 --> 00:11:03,090
‫in the route definition.

189
00:11:03,090 --> 00:11:07,380
‫So the data fetching really is fired off right here

190
00:11:07,380 --> 00:11:10,620
‫in the router itself, not in the component.

191
00:11:10,620 --> 00:11:12,900
‫And so if all of these components here

192
00:11:12,900 --> 00:11:14,490
‫would be fetching some data,

193
00:11:14,490 --> 00:11:18,060
‫then all of that would be happening here in this one place,

194
00:11:18,060 --> 00:11:21,030
‫which is something that we always strive for.

195
00:11:21,030 --> 00:11:24,390
‫So it's always good to have all the data loading

196
00:11:24,390 --> 00:11:26,220
‫and really many other things

197
00:11:26,220 --> 00:11:29,280
‫as well happening just in one place,

198
00:11:29,280 --> 00:11:33,060
‫so that we can see what's happening all at once.

199
00:11:33,060 --> 00:11:36,690
‫But anyway, after this long explanation

200
00:11:36,690 --> 00:11:40,950
‫of how data loading works in modern React Router,

201
00:11:40,950 --> 00:11:43,860
‫let's also use these capabilities

202
00:11:43,860 --> 00:11:46,387
‫to display a loading indicator right

203
00:11:46,387 --> 00:11:47,943
‫in the next video.

