1
00:00:00,000 --> 00:00:01,000
Now at the moment,

2
00:00:01,000 --> 00:00:06,000
this application has some minor problems.

3
00:00:06,000 --> 00:00:09,000
Most importantly, if I select a month here,

4
00:00:09,000 --> 00:00:11,000
we don't get any feedback initially

5
00:00:11,000 --> 00:00:12,000
until the data is loaded,

6
00:00:12,000 --> 00:00:15,000
which takes a while, and we got no feedback

7
00:00:15,000 --> 00:00:17,000
whilst we're waiting for the data.

8
00:00:17,000 --> 00:00:19,000
And that might be strange.

9
00:00:19,000 --> 00:00:24,000
Why are we getting no loading feedback when loading a month,

10
00:00:24,000 --> 00:00:28,000
even though we of course have a parent loading JS file?

11
00:00:29,000 --> 00:00:31,000
Well, we're not getting any feedback

12
00:00:31,000 --> 00:00:34,000
because when selecting a month,

13
00:00:34,000 --> 00:00:38,000
we already are on that filter page here,

14
00:00:38,000 --> 00:00:41,000
and therefore NextJS does not swap it

15
00:00:41,000 --> 00:00:43,000
for the loading fallback

16
00:00:43,000 --> 00:00:45,000
since we already have some data here.

17
00:00:45,000 --> 00:00:47,000
We're just loading some new data,

18
00:00:47,000 --> 00:00:49,000
but we already did load data before,

19
00:00:49,000 --> 00:00:53,000
so it's not showing us that loading fallback again.

20
00:00:54,000 --> 00:00:57,000
Now we can work around that

21
00:00:57,000 --> 00:01:00,000
by using a more granular approach

22
00:01:00,000 --> 00:01:03,000
of showing a loading fallback,

23
00:01:03,000 --> 00:01:07,000
an alternative to using the loading JS file,

24
00:01:07,000 --> 00:01:10,000
which, you by the way, can always use as an alternative,

25
00:01:10,000 --> 00:01:13,000
not just in situations like this.

26
00:01:13,000 --> 00:01:15,000
And that alternative

27
00:01:15,000 --> 00:01:20,000
uses the suspense component that is provided by React

28
00:01:20,000 --> 00:01:23,000
to tell NextJS in detail

29
00:01:23,000 --> 00:01:27,000
for which kind of data we wanna wait

30
00:01:27,000 --> 00:01:30,000
and under which circumstances

31
00:01:30,000 --> 00:01:33,000
a loading fallback should be shown.

32
00:01:33,000 --> 00:01:37,000
Now, how can we use suspense for that?

33
00:01:37,000 --> 00:01:38,000
Well, as a first step,

34
00:01:38,000 --> 00:01:41,000
we have to create a separate component,

35
00:01:41,000 --> 00:01:43,000
and we can do that in a separate file

36
00:01:43,000 --> 00:01:46,000
or in the same file as this page component.

37
00:01:46,000 --> 00:01:48,000
And here I'll just use that same file

38
00:01:48,000 --> 00:01:51,000
to keep those things together.

39
00:01:52,000 --> 00:01:55,000
Now you can give this component any name of your choice.

40
00:01:55,000 --> 00:01:57,000
I'll name it FilteredNews.

41
00:02:00,000 --> 00:02:01,000
Now here in this component,

42
00:02:01,000 --> 00:02:03,000
I'll of course get a props object

43
00:02:03,000 --> 00:02:08,000
and I expect up to two props to be passed to this component,

44
00:02:09,000 --> 00:02:12,000
the selected year

45
00:02:12,000 --> 00:02:15,000
or maybe just year to keep it a bit shorter

46
00:02:15,000 --> 00:02:16,000
and the selected month,

47
00:02:16,000 --> 00:02:19,000
though both might be undefined.

48
00:02:20,000 --> 00:02:24,000
And then in the end, I wanna move that code

49
00:02:24,000 --> 00:02:27,000
where I get the news forward a year

50
00:02:27,000 --> 00:02:30,000
out of the filtered news page

51
00:02:30,000 --> 00:02:33,000
into the filtered news component.

52
00:02:33,000 --> 00:02:35,000
And therefore this should become an async component,

53
00:02:35,000 --> 00:02:37,000
which it can,

54
00:02:37,000 --> 00:02:40,000
because all components, not just page components,

55
00:02:40,000 --> 00:02:44,000
are server components by default in NextJS.

56
00:02:46,000 --> 00:02:49,000
So I'll create that news variable

57
00:02:49,000 --> 00:02:52,000
and then I check if we have a year

58
00:02:52,000 --> 00:02:54,000
and we don't have a month.

59
00:02:54,000 --> 00:02:55,000
And in that case, I'll set my news to the news

60
00:02:55,000 --> 00:02:57,000
for a selected year,

61
00:02:57,000 --> 00:03:01,000
though it's no longer called selected year here,

62
00:03:01,000 --> 00:03:02,000
but instead just year.

63
00:03:03,000 --> 00:03:07,000
Else if we have a year and a month.

64
00:03:07,000 --> 00:03:12,000
So if we have both, news should be set equal to get news

65
00:03:12,000 --> 00:03:14,000
for a year and month,

66
00:03:14,000 --> 00:03:17,000
and I pass both the year and the month to that function.

67
00:03:19,000 --> 00:03:21,000
So now with that, I'm fetching my news like this,

68
00:03:21,000 --> 00:03:26,000
and then I wanna output that news list

69
00:03:26,000 --> 00:03:28,000
just as I did it before.

70
00:03:28,000 --> 00:03:31,000
So I'll actually grab this code

71
00:03:31,000 --> 00:03:33,000
where I also render some fallback

72
00:03:33,000 --> 00:03:35,000
in case we don't have any news

73
00:03:35,000 --> 00:03:39,000
and I'll cut this and add this here.

74
00:03:40,000 --> 00:03:42,000
And then I can just return

75
00:03:42,000 --> 00:03:47,000
that news content here like this.

76
00:03:47,000 --> 00:03:50,000
Now we should clean up the filtered news page.

77
00:03:50,000 --> 00:03:52,000
And there I still wanna extract

78
00:03:52,000 --> 00:03:54,000
the selected year and selected month,

79
00:03:54,000 --> 00:03:57,000
but we no longer need the news variable here

80
00:03:59,000 --> 00:04:03,000
and we also won't populate it here therefore.

81
00:04:03,000 --> 00:04:06,000
And I'll actually also improve this code a little bit

82
00:04:06,000 --> 00:04:08,000
and not fetch the same information twice.

83
00:04:08,000 --> 00:04:12,000
But instead, I'll just fetch my available years here

84
00:04:12,000 --> 00:04:14,000
and then use that fetched value

85
00:04:14,000 --> 00:04:18,000
as a default value for my links like this.

86
00:04:19,000 --> 00:04:23,000
And I now don't wanna output the news content here,

87
00:04:23,000 --> 00:04:27,000
but instead this newly added filtered news component

88
00:04:27,000 --> 00:04:29,000
to which we pass a year prop,

89
00:04:29,000 --> 00:04:31,000
which is set equal to selected year

90
00:04:31,000 --> 00:04:35,000
and a month prop, which is set equal to selected month.

91
00:04:38,000 --> 00:04:41,000
Now with that alone, nothing would change.

92
00:04:41,000 --> 00:04:44,000
If I now reload this page,

93
00:04:44,000 --> 00:04:47,000
we are still loading the data for a selected year

94
00:04:47,000 --> 00:04:49,000
and I can load the data for a selected month,

95
00:04:49,000 --> 00:04:53,000
but I still get no loading fallback.

96
00:04:54,000 --> 00:04:58,000
But now that we outsourced this data fetching logic

97
00:04:58,000 --> 00:05:02,000
where we fetched and use for a year or month

98
00:05:02,000 --> 00:05:05,000
into a separate React Server component,

99
00:05:05,000 --> 00:05:09,000
we can use that React suspense hook I mentioned before.

100
00:05:10,000 --> 00:05:15,000
So for that, we now wrap suspense around the component

101
00:05:15,000 --> 00:05:16,000
that does the data fetching

102
00:05:16,000 --> 00:05:21,000
for which we want to provide our own custom loading fallback

103
00:05:23,000 --> 00:05:26,000
and suspense must be imported from React.

104
00:05:26,000 --> 00:05:29,000
So you must import this component.

105
00:05:30,000 --> 00:05:33,000
And with it being wrapped around a component

106
00:05:33,000 --> 00:05:35,000
that fetches data,

107
00:05:35,000 --> 00:05:37,000
it will automatically register

108
00:05:37,000 --> 00:05:41,000
if that component is still fetching data

109
00:05:41,000 --> 00:05:45,000
and it allows us to show a fallback whilst that's the case.

110
00:05:45,000 --> 00:05:50,000
So here I can then say loading news or something like this.

111
00:05:50,000 --> 00:05:54,000
And with that, we then have a very granular way

112
00:05:54,000 --> 00:05:58,000
of telling NextJS that a part of the JSX code

113
00:05:58,000 --> 00:06:01,000
should be replaced with a fallback

114
00:06:01,000 --> 00:06:03,000
if that part is fetching data.

115
00:06:05,000 --> 00:06:07,000
With loading.js, it's less granular.

116
00:06:07,000 --> 00:06:09,000
There we're telling NextJS

117
00:06:09,000 --> 00:06:13,000
that an entire component, the entire page component actually

118
00:06:13,000 --> 00:06:18,000
should be replaced with that fallback if it's fetching data.

119
00:06:18,000 --> 00:06:20,000
But if we're then just re fetching data,

120
00:06:20,000 --> 00:06:23,000
it will not be replaced again.

121
00:06:23,000 --> 00:06:26,000
And if we want it to be more granular in general,

122
00:06:26,000 --> 00:06:30,000
we couldn't do it with a loading JS file,

123
00:06:30,000 --> 00:06:32,000
but we can be very granular

124
00:06:32,000 --> 00:06:35,000
by defining our own suspense boundaries.

125
00:06:36,000 --> 00:06:38,000
And therefore, with this added now,

126
00:06:38,000 --> 00:06:41,000
if I now reload, we got the same effect as before,

127
00:06:41,000 --> 00:06:42,000
but now you already see,

128
00:06:42,000 --> 00:06:44,000
we got the loading use fallback here,

129
00:06:44,000 --> 00:06:47,000
and if I now click on a month,

130
00:06:47,000 --> 00:06:50,000
we also see loading use here until the month appears.

131
00:06:50,000 --> 00:06:52,000
Though, as you can see,

132
00:06:52,000 --> 00:06:54,000
it actually still takes a short while

133
00:06:54,000 --> 00:06:58,000
until we see that fallback after I clicked on a month.

134
00:06:58,000 --> 00:07:02,000
And that's happening because technically NextJS

135
00:07:02,000 --> 00:07:05,000
is re rendering this page when we click on a month

136
00:07:05,000 --> 00:07:08,000
because we did change the route parameters

137
00:07:08,000 --> 00:07:12,000
and therefore it does re fetch the data for the header

138
00:07:12,000 --> 00:07:15,000
that's shown above the news list.

139
00:07:15,000 --> 00:07:16,000
And hence, for example, again,

140
00:07:16,000 --> 00:07:19,000
gets the available news years.

141
00:07:19,000 --> 00:07:23,000
And therefore we might wanna wrap this header

142
00:07:23,000 --> 00:07:25,000
with a suspense boundary as well

143
00:07:26,000 --> 00:07:29,000
so that we actually add another component.

144
00:07:29,000 --> 00:07:32,000
And again, we could outsource them into separate files,

145
00:07:32,000 --> 00:07:35,000
but since they do belong directly to this page,

146
00:07:35,000 --> 00:07:38,000
I'll keep them in the same file here for now.

147
00:07:38,000 --> 00:07:41,000
And I'll name this component Filter

148
00:07:41,000 --> 00:07:43,000
or FilterHeader, whatever.

149
00:07:43,000 --> 00:07:46,000
And this should also become a async component

150
00:07:46,000 --> 00:07:49,000
because it also is a React server component.

151
00:07:50,000 --> 00:07:54,000
And now we can grab this code here

152
00:07:54,000 --> 00:07:55,000
where we set up the links

153
00:07:56,000 --> 00:08:00,000
and cut that from the filtered news page,

154
00:08:00,000 --> 00:08:03,000
and instead add it here to the filter header

155
00:08:06,000 --> 00:08:11,000
and expect to get the year at month that was selected

156
00:08:11,000 --> 00:08:15,000
through the route parameters here as well.

157
00:08:15,000 --> 00:08:18,000
And then use month instead of selected month

158
00:08:18,000 --> 00:08:22,000
and year instead of selected year like this.

159
00:08:25,000 --> 00:08:30,000
And then of course also output that header.

160
00:08:30,000 --> 00:08:35,000
So here, I'll grab that header JSX code and cut it,

161
00:08:35,000 --> 00:08:39,000
and then go back here to my filter header

162
00:08:39,000 --> 00:08:44,000
and return it here like this.

163
00:08:44,000 --> 00:08:47,000
And now we can use the filter header

164
00:08:47,000 --> 00:08:52,000
in the filtered news page like this.

165
00:08:52,000 --> 00:08:56,000
And of course, all the past year and month to that.

166
00:08:58,000 --> 00:09:02,000
And again, we can now wrap this with suspense

167
00:09:03,000 --> 00:09:05,000
and say loading filter.

168
00:09:05,000 --> 00:09:08,000
But now we'll show different loading fallbacks

169
00:09:08,000 --> 00:09:11,000
for these different areas.

170
00:09:11,000 --> 00:09:14,000
And if they take different amounts of times to load,

171
00:09:14,000 --> 00:09:17,000
we'll show content as soon as it's ready

172
00:09:17,000 --> 00:09:19,000
because these two suspense boundaries

173
00:09:19,000 --> 00:09:22,000
do not wait on each other.

174
00:09:22,000 --> 00:09:26,000
Instead, each boundary will show its data once it's there

175
00:09:26,000 --> 00:09:28,000
and show its fallback until it's there,

176
00:09:28,000 --> 00:09:31,000
but it does not wait for any other data

177
00:09:31,000 --> 00:09:35,000
in any other suspense wrapped component to load.

178
00:09:36,000 --> 00:09:37,000
That's really great,

179
00:09:37,000 --> 00:09:40,000
and that gives you a really granular way

180
00:09:40,000 --> 00:09:42,000
of showing a fallback

181
00:09:42,000 --> 00:09:45,000
and handling the loading state of data

182
00:09:45,000 --> 00:09:47,000
in your page components.

183
00:09:49,000 --> 00:09:50,000
Now of course, here in my code,

184
00:09:50,000 --> 00:09:54,000
I actually still need to know about those available years

185
00:09:54,000 --> 00:09:59,000
to potentially show an error if we have an invalid filter,

186
00:10:00,000 --> 00:10:02,000
but actually we can move that code

187
00:10:02,000 --> 00:10:04,000
into the filter header as well.

188
00:10:05,000 --> 00:10:08,000
So therefore, I'll go to the filter header here

189
00:10:08,000 --> 00:10:10,000
and add the if check

190
00:10:10,000 --> 00:10:12,000
where I check if we have a year

191
00:10:12,000 --> 00:10:17,000
and the available years do not include that year

192
00:10:17,000 --> 00:10:18,000
or if we have a month

193
00:10:18,000 --> 00:10:21,000
and the available months for a year

194
00:10:21,000 --> 00:10:23,000
do not include that month.

195
00:10:23,000 --> 00:10:25,000
And in that case, I still throw an error

196
00:10:25,000 --> 00:10:26,000
and it will bubble up

197
00:10:26,000 --> 00:10:29,000
to the closest error handling component,

198
00:10:29,000 --> 00:10:32,000
so to the closest error JS file.

199
00:10:34,000 --> 00:10:35,000
And therefore, now if we save that and reload,

200
00:10:35,000 --> 00:10:39,000
you see we got two different loading fallbacks here

201
00:10:39,000 --> 00:10:42,000
and it looks like I forgot to rename

202
00:10:42,000 --> 00:10:45,000
one selected year occurrence.

203
00:10:45,000 --> 00:10:48,000
Yep, that should be year, not selected year.

204
00:10:50,000 --> 00:10:52,000
But with that, if we save that and we reload,

205
00:10:52,000 --> 00:10:54,000
we got these two different loading states,

206
00:10:54,000 --> 00:10:57,000
and then we got our data.

207
00:10:57,000 --> 00:10:58,000
And now if I click on that filter again,

208
00:10:58,000 --> 00:11:01,000
you see loading, filter loading use,

209
00:11:01,000 --> 00:11:04,000
and we therefore give the user a better feedback

210
00:11:04,000 --> 00:11:07,000
regarding what's happening behind the scenes.

211
00:11:07,000 --> 00:11:11,000
And of course, you can be as granular as you want to.

212
00:11:11,000 --> 00:11:15,000
You could use one suspense boundary for both components.

213
00:11:15,000 --> 00:11:19,000
So that would also work if you wanted to do that.

214
00:11:20,000 --> 00:11:23,000
This is all up to you as you see here,

215
00:11:23,000 --> 00:11:27,000
but that's the great thing about React and NextJS,

216
00:11:27,000 --> 00:11:30,000
you get a lot of tools and a lot of flexibility,

217
00:11:30,000 --> 00:11:33,000
and now you also know how to use these tools.

