1
00:00:02,000 --> 00:00:03,000
Now with routing added,

2
00:00:03,000 --> 00:00:07,000
we added another crucial feature to this application,

3
00:00:07,000 --> 00:00:09,000
a feature which is especially important

4
00:00:09,000 --> 00:00:12,000
in more complex web applications

5
00:00:12,000 --> 00:00:13,000
you might be building with React.

6
00:00:13,000 --> 00:00:18,000
And React router, at least if you have version 6.4

7
00:00:19,000 --> 00:00:23,000
or higher installed, also offers some amazing features

8
00:00:23,000 --> 00:00:26,000
that go beyond picking the right component

9
00:00:26,000 --> 00:00:27,000
for the right path.

10
00:00:27,000 --> 00:00:31,000
Instead, React router, when using version 6.4 or higher

11
00:00:31,000 --> 00:00:34,000
also helps with data fetching and data submission.

12
00:00:34,000 --> 00:00:37,000
And that's now the last part we're also going to explore

13
00:00:37,000 --> 00:00:38,000
in this crash course.

14
00:00:39,000 --> 00:00:42,000
Because of course here we are fetching data,

15
00:00:42,000 --> 00:00:45,000
in the Posts component, we have the PostsList component,

16
00:00:45,000 --> 00:00:49,000
and in there, we are fetching data.

17
00:00:49,000 --> 00:00:51,000
We have this useEffect hook here

18
00:00:51,000 --> 00:00:55,000
where we load our posts and set our posts.

19
00:00:55,000 --> 00:00:58,000
We also have to code for sending postData here

20
00:00:58,000 --> 00:01:00,000
but that code isn't used at the moment anymore

21
00:01:00,000 --> 00:01:02,000
and I'll get back to that later.

22
00:01:03,000 --> 00:01:05,000
But when it comes to fetching data,

23
00:01:05,000 --> 00:01:07,000
we could stick to useEffect.

24
00:01:07,000 --> 00:01:10,000
But when using React router version 6.4 or higher,

25
00:01:10,000 --> 00:01:13,000
we have a more convenient way of doing so.

26
00:01:13,000 --> 00:01:15,000
Because with that version,

27
00:01:15,000 --> 00:01:17,000
you can go to your route definitions

28
00:01:17,000 --> 00:01:19,000
to the route that needs data,

29
00:01:19,000 --> 00:01:21,000
so the Posts route here, for example,

30
00:01:21,000 --> 00:01:25,000
and you can add a loader property to that route definition.

31
00:01:26,000 --> 00:01:28,000
Now the loader property

32
00:01:28,000 --> 00:01:31,000
expects to get a function as a value,

33
00:01:31,000 --> 00:01:34,000
and React router will execute that function

34
00:01:34,000 --> 00:01:37,000
whenever that route gets activated,

35
00:01:37,000 --> 00:01:40,000
so whenever it's about to render this element.

36
00:01:40,000 --> 00:01:42,000
That's when this function gets executed

37
00:01:42,000 --> 00:01:45,000
and you can therefore use this function

38
00:01:45,000 --> 00:01:49,000
to load and prepare any data that might be needed

39
00:01:49,000 --> 00:01:50,000
by this route component

40
00:01:50,000 --> 00:01:54,000
or any other component used as part of that route,

41
00:01:54,000 --> 00:01:55,000
so any nested component

42
00:01:55,000 --> 00:01:58,000
used inside of the Posts component, for example.

43
00:02:00,000 --> 00:02:03,000
Now therefore, we could add the data fetching logic

44
00:02:03,000 --> 00:02:06,000
for sending that HTTP request here.

45
00:02:06,000 --> 00:02:09,000
But to keep this main JSX file lean,

46
00:02:09,000 --> 00:02:13,000
it's more common to go to your route component file,

47
00:02:13,000 --> 00:02:16,000
so in this case, the Posts.jsx file,

48
00:02:16,000 --> 00:02:19,000
and there, export an extra function,

49
00:02:19,000 --> 00:02:21,000
which typically is called loader

50
00:02:21,000 --> 00:02:23,000
though the name is up to you.

51
00:02:23,000 --> 00:02:25,000
But loader is a common convention

52
00:02:25,000 --> 00:02:27,000
since this will be the function

53
00:02:27,000 --> 00:02:29,000
that will be assigned to that loader property

54
00:02:29,000 --> 00:02:31,000
in the route definition.

55
00:02:31,000 --> 00:02:33,000
Now that loader function here

56
00:02:33,000 --> 00:02:35,000
still executes on the client side.

57
00:02:35,000 --> 00:02:38,000
It's still code that executes in the browser.

58
00:02:38,000 --> 00:02:41,000
And therefore, in there, you can do whatever you wanna do

59
00:02:41,000 --> 00:02:45,000
that could be done anywhere else in this app as well.

60
00:02:45,000 --> 00:02:46,000
Here I wanna fetch my posts.

61
00:02:46,000 --> 00:02:50,000
And therefore, I'll go to the PostsList component

62
00:02:50,000 --> 00:02:54,000
and copy these two lines of code here.

63
00:02:54,000 --> 00:02:57,000
The state updating code does not matter here

64
00:02:57,000 --> 00:02:58,000
because this loader function

65
00:02:58,000 --> 00:03:00,000
executes outside of the component

66
00:03:00,000 --> 00:03:03,000
and can't manipulate component state.

67
00:03:03,000 --> 00:03:06,000
You will still see how we then get the posts

68
00:03:06,000 --> 00:03:08,000
into the component a little bit later.

69
00:03:09,000 --> 00:03:12,000
So I cut the code for fetching data,

70
00:03:12,000 --> 00:03:14,000
and back in Posts.jsx,

71
00:03:14,000 --> 00:03:16,000
I'll paste it into this loader function.

72
00:03:17,000 --> 00:03:19,000
Now since I used the await keyword here,

73
00:03:19,000 --> 00:03:20,000
we should add async

74
00:03:20,000 --> 00:03:23,000
in front of that function to unlock that keyword,

75
00:03:23,000 --> 00:03:25,000
and we can't do that

76
00:03:25,000 --> 00:03:28,000
because this function which will be assigned

77
00:03:28,000 --> 00:03:31,000
to this loader property can be an async

78
00:03:31,000 --> 00:03:32,000
or a synchronous function.

79
00:03:32,000 --> 00:03:35,000
It may return a promise or it may not.

80
00:03:35,000 --> 00:03:38,000
React router does not care about it.

81
00:03:38,000 --> 00:03:40,000
But if it does return a promise,

82
00:03:40,000 --> 00:03:43,000
React router will wait for that promise to resolve

83
00:03:43,000 --> 00:03:47,000
before it then renders this route component,

84
00:03:47,000 --> 00:03:49,000
so this element which you specified here.

85
00:03:50,000 --> 00:03:52,000
And therefore here we can use async

86
00:03:52,000 --> 00:03:56,000
and then send our request to fetch all posts

87
00:03:56,000 --> 00:03:58,000
and extract the data.

88
00:03:58,000 --> 00:04:00,000
And then, that's the important part,

89
00:04:00,000 --> 00:04:03,000
we can return the data that we wanna expose

90
00:04:03,000 --> 00:04:07,000
to the element that is rendered for the active route.

91
00:04:08,000 --> 00:04:11,000
So in this case, resData.posts.

92
00:04:11,000 --> 00:04:14,000
I return that as part of this loader.

93
00:04:14,000 --> 00:04:19,000
And then in main.jsx, we can import this loader

94
00:04:19,000 --> 00:04:22,000
by editing this import here

95
00:04:22,000 --> 00:04:25,000
where we import the posts component function.

96
00:04:25,000 --> 00:04:28,000
And there, we can also import this loader,

97
00:04:28,000 --> 00:04:29,000
and I'll give it an alias

98
00:04:29,000 --> 00:04:33,000
since we might have more loaders from different routes

99
00:04:33,000 --> 00:04:36,000
and we don't wanna have name clashes.

100
00:04:36,000 --> 00:04:37,000
We could name this postsLoader,

101
00:04:37,000 --> 00:04:40,000
but of course this name is up to you.

102
00:04:40,000 --> 00:04:42,000
So in the end, it's now this loader function here

103
00:04:42,000 --> 00:04:44,000
which is assigned as a value

104
00:04:44,000 --> 00:04:47,000
for this loader property in this route definition.

105
00:04:47,000 --> 00:04:51,000
And therefore, React router will execute this function

106
00:04:51,000 --> 00:04:53,000
and wait for the promise to resolve

107
00:04:53,000 --> 00:04:55,000
before it then renders this element.

108
00:04:57,000 --> 00:04:59,000
And the data we return here in this loader

109
00:04:59,000 --> 00:05:02,000
is actually exposed to this element.

110
00:05:02,000 --> 00:05:05,000
React router will make sure that the data returned here

111
00:05:05,000 --> 00:05:08,000
can be accessed in this route element

112
00:05:08,000 --> 00:05:10,000
or in any nested component,

113
00:05:10,000 --> 00:05:13,000
so also in postsList, for example,

114
00:05:14,000 --> 00:05:16,000
that's what we can go to postsList.

115
00:05:16,000 --> 00:05:19,000
And there, we can now import

116
00:05:19,000 --> 00:05:22,000
and never hook from react-router-dom,

117
00:05:22,000 --> 00:05:27,000
and that would be the useLoaderData hook.

118
00:05:28,000 --> 00:05:30,000
Now this hook can be called

119
00:05:30,000 --> 00:05:31,000
inside of the component function.

120
00:05:31,000 --> 00:05:34,000
Like all Hooks, it must only be used

121
00:05:34,000 --> 00:05:36,000
inside of component functions in the end

122
00:05:36,000 --> 00:05:39,000
and that gives us the data that is returned

123
00:05:39,000 --> 00:05:43,000
by this loader that's assigned to this route

124
00:05:43,000 --> 00:05:44,000
which is the route that is active

125
00:05:44,000 --> 00:05:47,000
when the postsList component is rendered.

126
00:05:47,000 --> 00:05:50,000
So here I get my posts in the end

127
00:05:50,000 --> 00:05:54,000
because in my loader here, I'm returning the posts.

128
00:05:54,000 --> 00:05:57,000
So that's what I get here with help of use loader data.

129
00:05:57,000 --> 00:06:00,000
Therefore, we can get rid of that posts state.

130
00:06:00,000 --> 00:06:03,000
We can also get rid of the IsFetching state

131
00:06:03,000 --> 00:06:06,000
because the loading state of this route

132
00:06:06,000 --> 00:06:10,000
and this route component will be handled differently soon.

133
00:06:10,000 --> 00:06:13,000
And we can also get rid of this entire useEffect call here

134
00:06:13,000 --> 00:06:17,000
because we don't useEffect for data fetching anymore.

135
00:06:17,000 --> 00:06:20,000
Instead, we use this feature provided by React router.

136
00:06:20,000 --> 00:06:23,000
We therefore should also remove these imports

137
00:06:23,000 --> 00:06:25,000
of useState and useEffect.

138
00:06:25,000 --> 00:06:28,000
And then down there in the code,

139
00:06:28,000 --> 00:06:30,000
we no longer have this isFetching condition

140
00:06:30,000 --> 00:06:33,000
because we no longer have this isFetching state,

141
00:06:33,000 --> 00:06:34,000
so that should go away.

142
00:06:35,000 --> 00:06:39,000
And we also don't need to check for isFetching here anymore.

143
00:06:39,000 --> 00:06:41,000
I do, however, still want to check

144
00:06:41,000 --> 00:06:44,000
for whether we have posts or not.

145
00:06:44,000 --> 00:06:47,000
And posts is now simply coming from use loader data

146
00:06:47,000 --> 00:06:50,000
which gives us the data returned by the loader

147
00:06:50,000 --> 00:06:52,000
that was called for this route

148
00:06:52,000 --> 00:06:54,000
which is active at the moment.

149
00:06:55,000 --> 00:06:57,000
With that, if we save this,

150
00:06:57,000 --> 00:07:01,000
if I reload, you see nothing for a short period

151
00:07:01,000 --> 00:07:06,000
and then it actually loads the page and shows us the posts.

152
00:07:06,000 --> 00:07:08,000
And we see nothing initially

153
00:07:08,000 --> 00:07:10,000
because now the behavior is

154
00:07:10,000 --> 00:07:13,000
that as long as the loader executes,

155
00:07:13,000 --> 00:07:16,000
this route element isn't rendered.

156
00:07:16,000 --> 00:07:19,000
So React router waits for the loader to finish

157
00:07:19,000 --> 00:07:21,000
before it renders this element.

158
00:07:21,000 --> 00:07:23,000
And actually here, this even means

159
00:07:23,000 --> 00:07:25,000
that nothing is rendered on the screen

160
00:07:25,000 --> 00:07:28,000
if we first navigate to this page.

161
00:07:28,000 --> 00:07:32,000
If I instead navigate to this page after closing this page,

162
00:07:32,000 --> 00:07:35,000
it actually executes this behind the scenes

163
00:07:35,000 --> 00:07:37,000
and therefore then we don't get stuck

164
00:07:37,000 --> 00:07:40,000
and have an empty page for a brief moment.

165
00:07:40,000 --> 00:07:43,000
But if we visit this page for the first time,

166
00:07:43,000 --> 00:07:46,000
we see nothing initially until everything has been loaded.

167
00:07:47,000 --> 00:07:49,000
Now, this might not be the behavior you want

168
00:07:49,000 --> 00:07:51,000
and React router also gives you ways

169
00:07:51,000 --> 00:07:54,000
of showing pages earlier

170
00:07:54,000 --> 00:07:56,000
and not waiting for the loader to finish.

171
00:07:56,000 --> 00:08:00,000
And I do dive into more advanced React router features

172
00:08:00,000 --> 00:08:01,000
that help you in such situations as well

173
00:08:01,000 --> 00:08:03,000
in the complete guide course,

174
00:08:03,000 --> 00:08:06,000
but it's a bit beyond the scope of this crash course.

175
00:08:06,000 --> 00:08:09,000
The important takeaway here simply is

176
00:08:09,000 --> 00:08:11,000
that this loader is executed

177
00:08:11,000 --> 00:08:13,000
before this element is rendered.

178
00:08:13,000 --> 00:08:14,000
And whilst this might not be ideal

179
00:08:14,000 --> 00:08:17,000
in case of a slow back and as we have it here,

180
00:08:17,000 --> 00:08:19,000
it's a great solution

181
00:08:19,000 --> 00:08:23,000
for all cases where you don't have a slow backend.

182
00:08:23,000 --> 00:08:25,000
Because if I go back to my backend code

183
00:08:25,000 --> 00:08:28,000
and comment out this timeout here

184
00:08:28,000 --> 00:08:32,000
so that we don't have this slowdown on the backend anymore

185
00:08:32,000 --> 00:08:35,000
and I then restart this backend server,

186
00:08:36,000 --> 00:08:39,000
you now see that it loads pretty much instantly

187
00:08:39,000 --> 00:08:40,000
if I reload this page.

188
00:08:40,000 --> 00:08:43,000
And therefore now we have a great user experience again

189
00:08:43,000 --> 00:08:46,000
but we have way less code that must be written

190
00:08:46,000 --> 00:08:47,000
inside of the component

191
00:08:47,000 --> 00:08:50,000
since we're using this loader feature.

192
00:08:50,000 --> 00:08:53,000
And again, for situations with slow backends,

193
00:08:53,000 --> 00:08:54,000
there also would be solutions.

194
00:08:54,000 --> 00:08:57,000
And therefore you can handle all these scenarios

195
00:08:57,000 --> 00:09:00,000
with less code, which is of course great

196
00:09:00,000 --> 00:09:02,000
since it decreases the complexity of your app

197
00:09:02,000 --> 00:09:05,000
and means less work for you as a developer.

