1
00:00:02,000 --> 00:00:04,000
So it's great that we can now load data

2
00:00:04,000 --> 00:00:05,000
with that loader feature

3
00:00:05,000 --> 00:00:07,000
but what about submitting data?

4
00:00:07,000 --> 00:00:09,000
What about creating a new post?

5
00:00:09,000 --> 00:00:10,000
At the moment, this doesn't work.

6
00:00:10,000 --> 00:00:12,000
And of course, it should work.

7
00:00:12,000 --> 00:00:15,000
And for that, we can also leverage React Router.

8
00:00:16,000 --> 00:00:17,000
It's the NewPost component

9
00:00:17,000 --> 00:00:20,000
where we have this form in the end.

10
00:00:20,000 --> 00:00:21,000
And we've got a bunch of code

11
00:00:21,000 --> 00:00:24,000
for getting the user input

12
00:00:24,000 --> 00:00:27,000
and for then preventing the default behavior of the browser

13
00:00:27,000 --> 00:00:29,000
and doing something with the data.

14
00:00:31,000 --> 00:00:32,000
Now, what we could do

15
00:00:32,000 --> 00:00:34,000
is we could grab that code for sending that data

16
00:00:34,000 --> 00:00:36,000
to the backend,

17
00:00:36,000 --> 00:00:38,000
and cut it from addPostHandler here

18
00:00:38,000 --> 00:00:40,000
and actually get rid of addPostHandler

19
00:00:40,000 --> 00:00:44,000
in PostsList, making this component even leaner.

20
00:00:44,000 --> 00:00:46,000
And instead add it here

21
00:00:46,000 --> 00:00:48,000
in this NewPost component

22
00:00:48,000 --> 00:00:51,000
instead of calling onAddPost and onCancel.

23
00:00:53,000 --> 00:00:56,000
Instead of doing that, we could send that postData

24
00:00:56,000 --> 00:00:59,000
to the backend right from inside the NewPost component.

25
00:01:00,000 --> 00:01:02,000
And indeed, this would work

26
00:01:02,000 --> 00:01:05,000
but it's still a bunch of code we would have to write here,

27
00:01:05,000 --> 00:01:06,000
especially since we probably

28
00:01:06,000 --> 00:01:09,000
also wanna close the modal thereafter,

29
00:01:09,000 --> 00:01:12,000
which means that we then also have to add extra code

30
00:01:12,000 --> 00:01:15,000
for navigating to a different route programmatically.

31
00:01:16,000 --> 00:01:18,000
A better and more elegant approach

32
00:01:18,000 --> 00:01:21,000
is to also use a special feature offered

33
00:01:21,000 --> 00:01:22,000
by React Router

34
00:01:22,000 --> 00:01:26,000
because just as you can add loaders to your routes

35
00:01:26,000 --> 00:01:28,000
to load data before it gets activated

36
00:01:28,000 --> 00:01:31,000
and before the component gets rendered,

37
00:01:31,000 --> 00:01:33,000
you can add actions to routes.

38
00:01:33,000 --> 00:01:36,000
So to this route here, the create-post route,

39
00:01:36,000 --> 00:01:39,000
we can add an action by setting the action property.

40
00:01:39,000 --> 00:01:42,000
And just like loader, action wants a function

41
00:01:42,000 --> 00:01:43,000
as a value.

42
00:01:45,000 --> 00:01:47,000
This function, however, will now be triggered

43
00:01:47,000 --> 00:01:50,000
when a form is submitted in that route,

44
00:01:50,000 --> 00:01:53,000
which means that here in the NewPost component,

45
00:01:53,000 --> 00:01:56,000
we could export such a action function

46
00:01:56,000 --> 00:01:59,000
to again have that code close to the component

47
00:01:59,000 --> 00:02:00,000
to which it belongs.

48
00:02:00,000 --> 00:02:02,000
And then in here, we could add our code

49
00:02:02,000 --> 00:02:05,000
for sending that request.

50
00:02:05,000 --> 00:02:06,000
Like this.

51
00:02:07,000 --> 00:02:08,000
Now, we still need to get the postData

52
00:02:08,000 --> 00:02:11,000
but that's how we could get started.

53
00:02:11,000 --> 00:02:13,000
But how do we now get the data

54
00:02:13,000 --> 00:02:15,000
that's entered into the form by the user?

55
00:02:16,000 --> 00:02:20,000
Well, previously, we had to manage our own state for that.

56
00:02:20,000 --> 00:02:22,000
Now when we embrace React Router,

57
00:02:22,000 --> 00:02:24,000
this all gets much leaner again.

58
00:02:24,000 --> 00:02:26,000
We can delete that state

59
00:02:26,000 --> 00:02:30,000
and delete these functions that updated the state.

60
00:02:30,000 --> 00:02:32,000
We can also delete this submitHandler

61
00:02:32,000 --> 00:02:35,000
and therefore, also delete the useState import.

62
00:02:36,000 --> 00:02:39,000
And get rid of the onSubmit event listener

63
00:02:39,000 --> 00:02:40,000
on the form element

64
00:02:40,000 --> 00:02:44,000
and get rid of the onChange listeners on the inputs.

65
00:02:45,000 --> 00:02:48,000
So we already got rid of a lot of code here.

66
00:02:48,000 --> 00:02:50,000
And instead, all we have to do here

67
00:02:50,000 --> 00:02:54,000
is add a name attribute to our inputs.

68
00:02:54,000 --> 00:02:56,000
So in this case, to the text area here.

69
00:02:56,000 --> 00:02:58,000
And then assign a name,

70
00:02:58,000 --> 00:03:00,000
which we later wanna use for extracting

71
00:03:00,000 --> 00:03:02,000
and submitting our data.

72
00:03:02,000 --> 00:03:06,000
So for example, here my posts have a body,

73
00:03:06,000 --> 00:03:08,000
and an author field here.

74
00:03:08,000 --> 00:03:12,000
And if I wanna stick to that to body and author,

75
00:03:12,000 --> 00:03:16,000
I could give my text area here the name body,

76
00:03:16,000 --> 00:03:19,000
and this here, the name author.

77
00:03:20,000 --> 00:03:22,000
So that I already used the keys

78
00:03:22,000 --> 00:03:25,000
which I wanna use for storing my data here

79
00:03:25,000 --> 00:03:26,000
on these inputs.

80
00:03:27,000 --> 00:03:30,000
But what's the idea behind this name attribute?

81
00:03:30,000 --> 00:03:32,000
Well, it's a default HTML attribute

82
00:03:32,000 --> 00:03:34,000
that can be added to form inputs

83
00:03:34,000 --> 00:03:37,000
and by default, if a form is submitted,

84
00:03:37,000 --> 00:03:39,000
the browser will, as mentioned earlier,

85
00:03:39,000 --> 00:03:40,000
generate a request

86
00:03:40,000 --> 00:03:42,000
and it will try to send it to the server

87
00:03:42,000 --> 00:03:45,000
that served that website,

88
00:03:45,000 --> 00:03:46,000
which would be wrong

89
00:03:46,000 --> 00:03:48,000
because that server that's serving that website

90
00:03:48,000 --> 00:03:51,000
doesn't have any code to handle this request

91
00:03:51,000 --> 00:03:53,000
with the form data on the backend

92
00:03:53,000 --> 00:03:57,000
because we have no backend code as part of this React app.

93
00:03:57,000 --> 00:04:01,000
But that's now where React Router comes in.

94
00:04:01,000 --> 00:04:04,000
We can import a special component from React Router,

95
00:04:04,000 --> 00:04:07,000
and that would be the Form component with a capital F.

96
00:04:09,000 --> 00:04:10,000
And if we use that instead

97
00:04:10,000 --> 00:04:14,000
of the regular built-in Form element,

98
00:04:14,000 --> 00:04:16,000
React Router will handle the form submission

99
00:04:16,000 --> 00:04:19,000
and it will prevent that browser default

100
00:04:19,000 --> 00:04:21,000
of sending a request

101
00:04:21,000 --> 00:04:24,000
but it will still gather all the input data,

102
00:04:24,000 --> 00:04:27,000
still generate an object with that data for us,

103
00:04:27,000 --> 00:04:29,000
and that's the important part,

104
00:04:29,000 --> 00:04:33,000
call the action that is assigned to the route,

105
00:04:33,000 --> 00:04:34,000
which contains the form,

106
00:04:34,000 --> 00:04:36,000
the form with the capital F.

107
00:04:38,000 --> 00:04:41,000
So therefore now with this Form component being used,

108
00:04:41,000 --> 00:04:43,000
React Router will in the end make sure

109
00:04:43,000 --> 00:04:46,000
that this action here gets executed

110
00:04:46,000 --> 00:04:50,000
and therefore, we can now also import this action function,

111
00:04:50,000 --> 00:04:53,000
which I'm exporting here in NewPost.

112
00:04:53,000 --> 00:04:57,000
Import this from the NewPost component file here.

113
00:04:57,000 --> 00:04:58,000
The action.

114
00:04:58,000 --> 00:05:00,000
And maybe also give it an alias

115
00:05:00,000 --> 00:05:02,000
in case we had multiple actions

116
00:05:02,000 --> 00:05:05,000
from different routes to avoid clashes.

117
00:05:05,000 --> 00:05:07,000
That could be the newPostAction therefore.

118
00:05:08,000 --> 00:05:10,000
And assign that as a value

119
00:05:10,000 --> 00:05:13,000
for the action property down there, like this.

120
00:05:14,000 --> 00:05:15,000
So that in the end,

121
00:05:15,000 --> 00:05:18,000
it's now this action function

122
00:05:18,000 --> 00:05:20,000
that will be executed by React Router

123
00:05:20,000 --> 00:05:22,000
if this form here is submitted.

124
00:05:24,000 --> 00:05:26,000
Now one last thing I'll do here

125
00:05:26,000 --> 00:05:28,000
is I'll add the method prop here

126
00:05:28,000 --> 00:05:31,000
to this Form component and set it to post.

127
00:05:31,000 --> 00:05:32,000
Now, it's important to understand

128
00:05:32,000 --> 00:05:36,000
that no actual post request will be sent anywhere

129
00:05:36,000 --> 00:05:38,000
because this is still all client-side code

130
00:05:38,000 --> 00:05:41,000
but what React Router will do behind the scenes

131
00:05:41,000 --> 00:05:43,000
is it will generate a request object

132
00:05:43,000 --> 00:05:46,000
with that form data included in it.

133
00:05:46,000 --> 00:05:49,000
And it will give this request object a method,

134
00:05:49,000 --> 00:05:52,000
which we could then use here on the action

135
00:05:52,000 --> 00:05:55,000
to find out which form was submitted

136
00:05:55,000 --> 00:05:56,000
when this cation was triggered

137
00:05:56,000 --> 00:05:58,000
in case we had multiple forms

138
00:05:58,000 --> 00:06:01,000
that belong to the same route with the same action.

139
00:06:02,000 --> 00:06:04,000
And even without that, it's kind of a good idea

140
00:06:04,000 --> 00:06:08,000
to use the semantically correct HTTP verb

141
00:06:08,000 --> 00:06:10,000
and since we're creating a new post here,

142
00:06:10,000 --> 00:06:12,000
the post method makes sense

143
00:06:12,000 --> 00:06:15,000
because that's typically the HTTP method

144
00:06:15,000 --> 00:06:18,000
that is used for creating resources.

145
00:06:18,000 --> 00:06:20,000
So with that, no request is sent to the backend.

146
00:06:20,000 --> 00:06:23,000
Instead, this action will be executed

147
00:06:23,000 --> 00:06:27,000
and here, you actually get some data argument.

148
00:06:27,000 --> 00:06:31,000
This is passed in automatically by React Router.

149
00:06:31,000 --> 00:06:32,000
And that's not the data of the form,

150
00:06:32,000 --> 00:06:34,000
instead that is an object,

151
00:06:34,000 --> 00:06:37,000
which for example, has a request property

152
00:06:37,000 --> 00:06:40,000
with that request object that's generated

153
00:06:40,000 --> 00:06:42,000
and built by React Router.

154
00:06:42,000 --> 00:06:45,000
So React Router calls this action function

155
00:06:45,000 --> 00:06:47,000
and passes this object

156
00:06:47,000 --> 00:06:48,000
that includes the request object

157
00:06:48,000 --> 00:06:51,000
that was generated to this action function.

158
00:06:52,000 --> 00:06:55,000
Therefore here, we can actually use object destructuring

159
00:06:55,000 --> 00:06:59,000
to get hold of that request object like this.

160
00:06:59,000 --> 00:07:02,000
And now this request object has a formData method.

161
00:07:03,000 --> 00:07:05,000
And when you execute that formData method,

162
00:07:05,000 --> 00:07:09,000
you get access to the data encoded in that form,

163
00:07:09,000 --> 00:07:12,000
so the data that was extracted by React Router

164
00:07:12,000 --> 00:07:16,000
when it analyzed that form and called that action.

165
00:07:18,000 --> 00:07:20,000
Now, formData actually yields a promise,

166
00:07:20,000 --> 00:07:22,000
so we should turn this into a async function

167
00:07:22,000 --> 00:07:24,000
so that we can use await.

168
00:07:24,000 --> 00:07:27,000
And then here we got our formData object.

169
00:07:27,000 --> 00:07:30,000
And that is a rather complex object.

170
00:07:30,000 --> 00:07:32,000
It's not a plain key-value store.

171
00:07:32,000 --> 00:07:34,000
Instead, it's a object that, for example,

172
00:07:34,000 --> 00:07:36,000
has a get method,

173
00:07:36,000 --> 00:07:38,000
which you could call to get the value provided

174
00:07:38,000 --> 00:07:40,000
for the body field, like this.

175
00:07:41,000 --> 00:07:44,000
That's how you could then extract the data

176
00:07:44,000 --> 00:07:46,000
that was provided by the user.

177
00:07:46,000 --> 00:07:48,000
Now, an easier approach here

178
00:07:48,000 --> 00:07:51,000
is to instead create a postData constant

179
00:07:51,000 --> 00:07:54,000
and use the built-in Object class

180
00:07:54,000 --> 00:07:58,000
and call fromEntries and pass this formData object to it.

181
00:07:59,000 --> 00:08:01,000
Under the hood, this will simply then create

182
00:08:01,000 --> 00:08:04,000
a basic key-value object

183
00:08:04,000 --> 00:08:05,000
where you have a body key

184
00:08:05,000 --> 00:08:09,000
with some value, and an author key with some value

185
00:08:09,000 --> 00:08:12,000
in our case here since we have body and author

186
00:08:12,000 --> 00:08:16,000
as named values in this form.

187
00:08:17,000 --> 00:08:19,000
So that's how we can extract the formData

188
00:08:19,000 --> 00:08:21,000
with help of React Router.

189
00:08:21,000 --> 00:08:24,000
Again, all still happening on the client side here.

190
00:08:25,000 --> 00:08:27,000
And therefore now we got the postData we need

191
00:08:27,000 --> 00:08:29,000
for sending that request.

192
00:08:30,000 --> 00:08:32,000
Here we can also await this to wait

193
00:08:32,000 --> 00:08:34,000
for the request to be sent.

194
00:08:34,000 --> 00:08:36,000
We could also get the response

195
00:08:36,000 --> 00:08:38,000
and analyze the response,

196
00:08:38,000 --> 00:08:41,000
for example, to find out if something went wrong

197
00:08:41,000 --> 00:08:43,000
but I'll not do that here.

198
00:08:43,000 --> 00:08:46,000
And instead now, after sending this request,

199
00:08:46,000 --> 00:08:50,000
we can also call another function provided

200
00:08:50,000 --> 00:08:51,000
by react-router-dom

201
00:08:51,000 --> 00:08:53,000
and that would be the redirect function.

202
00:08:54,000 --> 00:08:57,000
This is imported from react-router-dom

203
00:08:57,000 --> 00:09:01,000
and you can call it in your action and loader functions

204
00:09:01,000 --> 00:09:04,000
to return the result of calling this function here.

205
00:09:05,000 --> 00:09:09,000
Now, what redirect does is it generates a response object,

206
00:09:09,000 --> 00:09:11,000
which in the end is then returned by this action.

207
00:09:11,000 --> 00:09:14,000
And if you return such a response object,

208
00:09:14,000 --> 00:09:17,000
React Router will look into that object

209
00:09:17,000 --> 00:09:18,000
and if it's a redirect response,

210
00:09:18,000 --> 00:09:21,000
which is the kind of response that is generated

211
00:09:21,000 --> 00:09:24,000
by calling redirect, React Router will simply move

212
00:09:24,000 --> 00:09:25,000
to that different route

213
00:09:25,000 --> 00:09:28,000
to which you're trying to redirect.

214
00:09:28,000 --> 00:09:31,000
So here we could path a path of slash here

215
00:09:31,000 --> 00:09:34,000
to make sure that after this action was called,

216
00:09:34,000 --> 00:09:38,000
we actually make React Router load a different route,

217
00:09:38,000 --> 00:09:41,000
the route with the path slash,

218
00:09:41,000 --> 00:09:43,000
which in this case is, of course, this route.

219
00:09:43,000 --> 00:09:46,000
So that we leave the create-post route

220
00:09:46,000 --> 00:09:48,000
and we move to this route instead.

221
00:09:48,000 --> 00:09:52,000
That's how we can initialize this navigation action.

222
00:09:52,000 --> 00:09:54,000
Again, all performed by React Router here.

223
00:09:54,000 --> 00:09:57,000
There is no backend code involved here.

224
00:09:57,000 --> 00:09:59,000
We're just sending a request to the backend

225
00:09:59,000 --> 00:10:02,000
but this code here all runs on the client side

226
00:10:02,000 --> 00:10:04,000
in the browser.

227
00:10:04,000 --> 00:10:07,000
But with that all added, if we save everything

228
00:10:07,000 --> 00:10:10,000
and we go back and go to the New Post area

229
00:10:10,000 --> 00:10:15,000
and try to add a new post, like this,

230
00:10:15,000 --> 00:10:18,000
you see I am redirected.

231
00:10:18,000 --> 00:10:19,000
This new post shows up here.

232
00:10:19,000 --> 00:10:22,000
If I reload, it still shows up here,

233
00:10:22,000 --> 00:10:24,000
so it was indeed sent to the backend.

234
00:10:24,000 --> 00:10:26,000
We can also see it in posts.json there.

235
00:10:26,000 --> 00:10:30,000
And therefore, this proves that this action works

236
00:10:30,000 --> 00:10:31,000
the way it should

237
00:10:31,000 --> 00:10:34,000
and we're now using React Router for sending

238
00:10:34,000 --> 00:10:35,000
and for fetching data.

239
00:10:37,000 --> 00:10:40,000
And as a result, you can see that our components

240
00:10:40,000 --> 00:10:42,000
got much leaner.

241
00:10:42,000 --> 00:10:44,000
We don't have to manually keep track

242
00:10:44,000 --> 00:10:45,000
of what was entered.

243
00:10:45,000 --> 00:10:48,000
We don't have to manually handle the form submission

244
00:10:48,000 --> 00:10:50,000
and prevent the default.

245
00:10:50,000 --> 00:10:51,000
We have to do none of that.

246
00:10:51,000 --> 00:10:53,000
We instead embrace React Router

247
00:10:53,000 --> 00:10:55,000
for sending and getting data,

248
00:10:55,000 --> 00:10:57,000
for navigation between pages,

249
00:10:57,000 --> 00:11:00,000
and that's why React Router is awesome.

250
00:11:00,000 --> 00:11:03,000
Also, for simple demos like this one,

251
00:11:03,000 --> 00:11:06,000
but especially, of course, for more complex websites.

