Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,200 --> 00:00:05,720
So as mentioned at the end of last lecture,
2
00:00:05,720 --> 00:00:07,560
we have a working code here
3
00:00:07,560 --> 00:00:09,770
but we have a lot of duplication.
4
00:00:09,770 --> 00:00:13,150
We're not duplicating the exact same words.
5
00:00:13,150 --> 00:00:15,180
These constants are named differently.
6
00:00:15,180 --> 00:00:17,340
This logic here is different,
7
00:00:17,340 --> 00:00:20,640
but the overall logic, the overall structure
8
00:00:20,640 --> 00:00:23,230
is of course exactly the same.
9
00:00:23,230 --> 00:00:26,960
And if we think about a more complex form like this one
10
00:00:26,960 --> 00:00:29,150
which actually isn't too complex
11
00:00:29,150 --> 00:00:31,980
but which has at least three inputs
12
00:00:31,980 --> 00:00:35,290
then we would be repeating that same structure,
13
00:00:35,290 --> 00:00:39,140
that same code in the end three times.
14
00:00:39,140 --> 00:00:41,090
And that's not what we wanna do.
15
00:00:41,090 --> 00:00:44,040
So instead we typically want to outsource
16
00:00:44,040 --> 00:00:45,460
some logic somewhere.
17
00:00:45,460 --> 00:00:48,800
We don't want to retype and repeat it all the time.
18
00:00:48,800 --> 00:00:50,793
And how can we best do that?
19
00:00:51,790 --> 00:00:56,160
You could consider creating a separate input Component
20
00:00:56,160 --> 00:00:59,770
so that you will replace this code down there
21
00:00:59,770 --> 00:01:01,400
with the input Component.
22
00:01:01,400 --> 00:01:04,790
And inside of that input Component you then have
23
00:01:04,790 --> 00:01:06,460
that logic for validating it,
24
00:01:06,460 --> 00:01:10,710
for checking its touch status and so on.
25
00:01:10,710 --> 00:01:13,060
And that would probably work.
26
00:01:13,060 --> 00:01:14,950
That is something you could do.
27
00:01:14,950 --> 00:01:18,580
The only thing that could become a bit more tricky then
28
00:01:18,580 --> 00:01:22,050
or where you would need to find a solution
29
00:01:22,050 --> 00:01:26,480
would be for managing the overall form validity.
30
00:01:26,480 --> 00:01:29,010
Because if you manage every input
31
00:01:29,010 --> 00:01:32,060
as an individual closed thing,
32
00:01:32,060 --> 00:01:34,310
and you know if the input is valid or not,
33
00:01:34,310 --> 00:01:37,080
you then also need a way of letting the overall form
34
00:01:37,080 --> 00:01:39,460
know if it's valid or not.
35
00:01:39,460 --> 00:01:41,140
And that could certainly be done
36
00:01:41,140 --> 00:01:44,080
with props and passing functions to props
37
00:01:44,080 --> 00:01:47,600
and calling them from inside the input Component and so on.
38
00:01:47,600 --> 00:01:49,270
But there always is another approach
39
00:01:49,270 --> 00:01:52,100
which I tend to prefer here.
40
00:01:52,100 --> 00:01:54,740
And that would be a custom hook.
41
00:01:54,740 --> 00:01:57,280
We can use a custom hook to manage all
42
00:01:57,280 --> 00:01:59,560
that state logic in there.
43
00:01:59,560 --> 00:02:02,300
And let me show you how we could do that.
44
00:02:02,300 --> 00:02:06,000
For this I'll add a new folder in this project here.
45
00:02:06,000 --> 00:02:08,650
I'll name it hooks next to Components
46
00:02:08,650 --> 00:02:12,350
and I'll then add a use input JS file
47
00:02:12,350 --> 00:02:15,530
because it will be a hook for managing the state
48
00:02:15,530 --> 00:02:17,610
and the logic for an input.
49
00:02:17,610 --> 00:02:22,610
So in here, I'll add my use input hook function
50
00:02:24,130 --> 00:02:26,940
and I will export it as a default here
51
00:02:27,790 --> 00:02:32,790
and now in this hook function, I want to manage the value
52
00:02:34,110 --> 00:02:37,290
of a given input, the touch state.
53
00:02:37,290 --> 00:02:40,453
I want to infer its validity.
54
00:02:41,470 --> 00:02:44,520
Also combined of course with the touch state.
55
00:02:44,520 --> 00:02:46,450
Now, of course this hook should then
56
00:02:46,450 --> 00:02:48,780
also be flexible though.
57
00:02:48,780 --> 00:02:52,040
The concrete validation logic should be passed into the hook
58
00:02:52,040 --> 00:02:56,320
from outside, but that is something we can build.
59
00:02:56,320 --> 00:02:58,740
And I'll start by copying the entered name
60
00:02:58,740 --> 00:03:01,150
and entered name touched states here
61
00:03:01,150 --> 00:03:03,680
and add them into use input function.
62
00:03:03,680 --> 00:03:07,250
For this of course here in this use input JS file
63
00:03:07,250 --> 00:03:10,233
we need to import useState from React.
64
00:03:11,230 --> 00:03:15,990
Then I'll rename this here to entered value
65
00:03:15,990 --> 00:03:20,470
and set entered value to make it more generic.
66
00:03:20,470 --> 00:03:25,470
And that here is touched and set is touched.
67
00:03:28,000 --> 00:03:32,000
Now as a next step, we can copy our inferred state here
68
00:03:32,000 --> 00:03:33,210
so to say.
69
00:03:33,210 --> 00:03:36,260
So these two constants entered name as valid
70
00:03:36,260 --> 00:03:38,740
and name input as invalid.
71
00:03:38,740 --> 00:03:41,810
I'll copy those and also give those better names.
72
00:03:41,810 --> 00:03:44,670
I'll name the first one value is valid
73
00:03:45,630 --> 00:03:47,880
and the second one could get a name
74
00:03:47,880 --> 00:03:51,700
of has error because in the end here we control
75
00:03:51,700 --> 00:03:54,173
whether an error should be shown or not.
76
00:03:55,050 --> 00:03:56,450
Now for value is valid.
77
00:03:56,450 --> 00:04:00,280
I check the entered value here and for has error
78
00:04:00,280 --> 00:04:02,420
I then use value is valid.
79
00:04:02,420 --> 00:04:05,290
And if it's not valid, combined with is touched.
80
00:04:05,290 --> 00:04:09,260
I find out whether we wanna show an error or not.
81
00:04:09,260 --> 00:04:11,800
Now this validation logic however,
82
00:04:11,800 --> 00:04:13,890
shouldn't be hard-coded here.
83
00:04:13,890 --> 00:04:17,360
Instead I want to get the logic for that from outside
84
00:04:17,360 --> 00:04:19,829
where this hook gets used.
85
00:04:19,829 --> 00:04:21,519
But that's no problem.
86
00:04:21,519 --> 00:04:23,780
We can expect a function
87
00:04:23,780 --> 00:04:26,770
as an argument to this custom hook function.
88
00:04:26,770 --> 00:04:30,433
Let's say the validate value function.
89
00:04:31,460 --> 00:04:35,010
So I expect that this parameter receives a function
90
00:04:35,010 --> 00:04:36,620
as a value.
91
00:04:36,620 --> 00:04:39,700
So that here for a value is valid.
92
00:04:39,700 --> 00:04:42,540
I can execute validate value
93
00:04:42,540 --> 00:04:46,463
and just pass in the entered value we currently have.
94
00:04:47,570 --> 00:04:50,330
And then this hook could return something.
95
00:04:50,330 --> 00:04:53,260
It could return an object, could also be an array,
96
00:04:53,260 --> 00:04:55,310
but one of the two, because I wanna return more
97
00:04:55,310 --> 00:04:56,590
than one thing.
98
00:04:56,590 --> 00:04:59,770
And then this object I'll return the value
99
00:04:59,770 --> 00:05:02,470
which is the entered value.
100
00:05:02,470 --> 00:05:04,820
I'll return has error
101
00:05:04,820 --> 00:05:08,340
which holds the results stored in has error.
102
00:05:08,340 --> 00:05:09,950
And since we got the same names here
103
00:05:09,950 --> 00:05:12,430
we can use the modern JavaScript syntax
104
00:05:12,430 --> 00:05:14,970
of just listing this once.
105
00:05:14,970 --> 00:05:17,240
And it'll automatically be expanded
106
00:05:17,240 --> 00:05:19,540
to this here behind the scenes.
107
00:05:19,540 --> 00:05:21,030
And we will also need a way
108
00:05:21,030 --> 00:05:23,473
of letting the Components that uses this hook
109
00:05:23,473 --> 00:05:25,090
set the entered value
110
00:05:25,090 --> 00:05:28,070
and set detached state thereafter.
111
00:05:28,070 --> 00:05:31,280
Now for that we could go back to simple input
112
00:05:31,280 --> 00:05:33,860
and copy the name input change handler
113
00:05:35,160 --> 00:05:37,540
into use input as a function
114
00:05:38,700 --> 00:05:43,700
and copy the name input blur handler into our hook function.
115
00:05:45,000 --> 00:05:50,000
And rename the functions to value change handler
116
00:05:50,650 --> 00:05:54,910
and call set entered value here.
117
00:05:54,910 --> 00:05:58,020
And then all the input blur handler
118
00:05:58,020 --> 00:06:01,373
and call set is touched here.
119
00:06:02,280 --> 00:06:05,730
And when we return, I wanna expose those functions.
120
00:06:05,730 --> 00:06:08,050
So I'll expose to value change handler
121
00:06:08,050 --> 00:06:10,513
and the input blur handler.
122
00:06:11,500 --> 00:06:14,890
So that these functions which are defined in the hook
123
00:06:14,890 --> 00:06:18,830
can be called from the place where to hook is being used.
124
00:06:18,830 --> 00:06:22,053
So can be called from the Components that uses that hook.
125
00:06:23,900 --> 00:06:26,440
Now with that can use this custom hook
126
00:06:26,440 --> 00:06:29,313
in the simple input Component.
127
00:06:29,313 --> 00:06:33,570
There we can now import use input
128
00:06:33,570 --> 00:06:38,570
from going up one level hooks use input
129
00:06:40,120 --> 00:06:45,120
and then call use input here and then extract values
130
00:06:46,130 --> 00:06:48,723
from the result returned by use input.
131
00:06:49,830 --> 00:06:52,490
Use input returns such an object
132
00:06:52,490 --> 00:06:55,780
hence we can use object de-structuring to pull
133
00:06:55,780 --> 00:06:58,960
out those keys from that returned object
134
00:06:58,960 --> 00:07:02,640
and store the values and brand new constants.
135
00:07:02,640 --> 00:07:05,210
So we can for example, extract the value
136
00:07:05,210 --> 00:07:07,710
and then also assign an alias
137
00:07:07,710 --> 00:07:12,327
with the colon here and name this entered name
138
00:07:14,090 --> 00:07:17,040
and also pull out the has error state
139
00:07:17,040 --> 00:07:22,040
and maybe named as name input has error.
140
00:07:22,380 --> 00:07:24,760
Those aliases of course are up to you
141
00:07:25,840 --> 00:07:28,990
and also extract the value change handler
142
00:07:28,990 --> 00:07:33,610
and give this an alias of name changed handler
143
00:07:34,610 --> 00:07:38,280
and get access to the input blur handler
144
00:07:38,280 --> 00:07:43,280
and give it an alias of name blur handler
145
00:07:43,660 --> 00:07:44,993
or something like this.
146
00:07:46,320 --> 00:07:48,203
So that this is how we use the hook,
147
00:07:49,060 --> 00:07:51,980
but we also need to pass a value into the hook.
148
00:07:51,980 --> 00:07:56,800
And that's this validate value function, which we call here.
149
00:07:56,800 --> 00:08:00,340
So for this we could define an inline function here
150
00:08:00,340 --> 00:08:05,340
where we get some value and then return the result
151
00:08:05,810 --> 00:08:08,350
of calling trim on that value and comparing it
152
00:08:08,350 --> 00:08:10,010
with an empty string.
153
00:08:10,010 --> 00:08:12,092
So the logic we have down there just
154
00:08:12,092 --> 00:08:15,570
with value instead of entered name.
155
00:08:15,570 --> 00:08:18,150
Now this is an anonymous error function
156
00:08:18,150 --> 00:08:22,470
which is not executed here but defined here in line
157
00:08:22,470 --> 00:08:25,100
which is then passed to use input.
158
00:08:25,100 --> 00:08:28,310
So it's received on this validate value parameter.
159
00:08:28,310 --> 00:08:31,410
And then this function, this function here
160
00:08:31,410 --> 00:08:34,990
which be defined here is actually executed
161
00:08:34,990 --> 00:08:36,520
in this line here.
162
00:08:36,520 --> 00:08:38,340
That's where it's being called.
163
00:08:38,340 --> 00:08:40,120
And the entered value
164
00:08:40,120 --> 00:08:44,710
which is this state we're managing here is the value passed
165
00:08:44,710 --> 00:08:46,560
into this function.
166
00:08:46,560 --> 00:08:49,340
Can be a bit tricky to wrap your head around,
167
00:08:49,340 --> 00:08:52,230
but in the end it's just regular JavaScript
168
00:08:52,230 --> 00:08:54,050
where we are passing a function
169
00:08:54,050 --> 00:08:55,883
as a value to another function.
170
00:08:57,030 --> 00:09:00,070
And with that, we can customize the validation logic
171
00:09:00,070 --> 00:09:03,300
in the Component where we need this hook
172
00:09:03,300 --> 00:09:06,163
and still execute it inside of the hook.
173
00:09:07,660 --> 00:09:09,420
And that now allows us to get rid
174
00:09:09,420 --> 00:09:13,210
of these two state slices here for the entered name.
175
00:09:13,210 --> 00:09:17,070
It allows us to get rid of these two constants here.
176
00:09:17,070 --> 00:09:21,140
Entered name is valid and name input is invalid.
177
00:09:21,140 --> 00:09:25,880
And instead use these pulled out Constants here.
178
00:09:25,880 --> 00:09:28,130
And for example here we are then actually
179
00:09:28,130 --> 00:09:30,870
missing information about the validity.
180
00:09:30,870 --> 00:09:33,100
We know if there is an error or not
181
00:09:33,100 --> 00:09:35,410
but that's not just the validity
182
00:09:35,410 --> 00:09:38,720
but the validity combined with the touch state.
183
00:09:38,720 --> 00:09:41,670
And therefore to expose just the validity
184
00:09:41,670 --> 00:09:44,030
of an input to the Component.
185
00:09:44,030 --> 00:09:49,030
I will actually also return value is valid here
186
00:09:49,360 --> 00:09:51,900
maybe on it is valid key.
187
00:09:51,900 --> 00:09:54,560
So that we also expose that information
188
00:09:54,560 --> 00:09:57,533
from the hook to the Component where we use it.
189
00:09:58,840 --> 00:10:02,660
And then in the Component we can also extract is valid
190
00:10:02,660 --> 00:10:07,390
and store this in a entered name is valid
191
00:10:07,390 --> 00:10:10,194
constant by assigning this alias
192
00:10:10,194 --> 00:10:14,853
and then entered name is valid can be used here again.
193
00:10:16,250 --> 00:10:18,730
Now we can get rid of the name inputs change handler
194
00:10:18,730 --> 00:10:21,783
function here and of the name input blur handler.
195
00:10:23,410 --> 00:10:25,450
And instead we'll use the name changed handler
196
00:10:25,450 --> 00:10:26,770
and the name blur handler
197
00:10:26,770 --> 00:10:28,900
which we're getting out of the hook.
198
00:10:28,900 --> 00:10:30,820
So down there in JSX.
199
00:10:30,820 --> 00:10:33,690
I connect the name change handler
200
00:10:33,690 --> 00:10:35,963
and the name blur handler.
201
00:10:37,960 --> 00:10:41,410
Here instead of using name input is invalid.
202
00:10:41,410 --> 00:10:45,300
I will use name has error, name input has error
203
00:10:45,300 --> 00:10:48,070
which we're also getting from the custom hook.
204
00:10:48,070 --> 00:10:50,720
And then here for the form submission handler
205
00:10:50,720 --> 00:10:53,520
where I want to change the touch status
206
00:10:53,520 --> 00:10:56,780
and where I want to reset the form.
207
00:10:56,780 --> 00:10:59,420
We can get rid of this line of code
208
00:10:59,420 --> 00:11:01,330
because the form can't be submitted
209
00:11:01,330 --> 00:11:04,320
if the inputs are invalid anyways.
210
00:11:04,320 --> 00:11:08,530
So we don't need to Mark the inputs as touched here
211
00:11:08,530 --> 00:11:11,480
but of course you want to be able to reset the form.
212
00:11:11,480 --> 00:11:13,800
And therefore we can go back to the custom hook
213
00:11:13,800 --> 00:11:16,186
and add a third function here.
214
00:11:16,186 --> 00:11:21,186
Reset function where we simply call set entered value
215
00:11:22,980 --> 00:11:24,870
and set this to an empty string.
216
00:11:24,870 --> 00:11:28,360
And set is touched and set this to false.
217
00:11:28,360 --> 00:11:30,280
And then we just need to expose that.
218
00:11:30,280 --> 00:11:33,460
So that we also return the reset function
219
00:11:33,460 --> 00:11:37,883
as a value in a reset key in that overall returned object.
220
00:11:39,400 --> 00:11:41,950
And in simple input JS
221
00:11:41,950 --> 00:11:45,850
we can then get access to this reset function
222
00:11:45,850 --> 00:11:50,850
and maybe name it reset name input, give it this alias.
223
00:11:51,780 --> 00:11:54,180
And then the form submission handlers.
224
00:11:54,180 --> 00:11:57,380
We can then just call reset name input here.
225
00:11:57,380 --> 00:12:00,526
Now down there where we inferred a CSS classes.
226
00:12:00,526 --> 00:12:05,526
I now wanna use the name input has error data piece
227
00:12:06,740 --> 00:12:08,090
which we get from the hook.
228
00:12:09,240 --> 00:12:13,830
And with that, if we reload this name behaves just like
229
00:12:13,830 --> 00:12:18,440
before and the overall form also behaves just like before.
230
00:12:18,440 --> 00:12:20,838
If I enter something valid here, we can submit it.
231
00:12:20,838 --> 00:12:23,280
If this is invalid, we can't.
232
00:12:23,280 --> 00:12:24,830
If I reload, if I click in there
233
00:12:24,830 --> 00:12:26,660
and out of there, it's invalid.
234
00:12:26,660 --> 00:12:30,110
This all works like before but now with a custom hook
235
00:12:30,110 --> 00:12:34,410
and now we can therefore also replace the email state
236
00:12:34,410 --> 00:12:37,680
the entered email state with our custom hook.
237
00:12:37,680 --> 00:12:39,730
Feel free to try this on your own.
238
00:12:39,730 --> 00:12:42,423
We're going to do it together in the next lecture.
18789
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.