Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,130 --> 00:00:04,760
The next hook I want to show you allows us
2
00:00:04,760 --> 00:00:08,890
to interact with the Input Components imperatively,
3
00:00:08,890 --> 00:00:12,000
which means not by parsing some state to it
4
00:00:12,000 --> 00:00:14,560
that then changes something in the Component,
5
00:00:14,560 --> 00:00:18,070
but by calling a function inside of a Component,
6
00:00:18,070 --> 00:00:21,280
for example, which is something you won't need to do often
7
00:00:21,280 --> 00:00:23,670
and you shouldn't do often because it's not
8
00:00:23,670 --> 00:00:25,760
the typical React pattern you want,
9
00:00:25,760 --> 00:00:28,000
but sometimes it is helpful.
10
00:00:28,000 --> 00:00:31,240
Now it will become clearer what I mean in a second.
11
00:00:31,240 --> 00:00:33,780
First of all, let's remove this disabled prop
12
00:00:33,780 --> 00:00:34,720
from the button.
13
00:00:34,720 --> 00:00:36,390
I don't want to disable the button.
14
00:00:36,390 --> 00:00:38,203
It should always be clickable now.
15
00:00:39,070 --> 00:00:40,990
Second into submitHandler,
16
00:00:40,990 --> 00:00:43,240
since the button is not always clickable,
17
00:00:43,240 --> 00:00:45,620
I want to check if the form is valid
18
00:00:45,620 --> 00:00:48,770
and only if it is, I will call all onLogin.
19
00:00:50,130 --> 00:00:52,620
Otherwise, and that's not the interesting part,
20
00:00:52,620 --> 00:00:57,620
I want to basically focus the first invalid Input I find.
21
00:00:59,390 --> 00:01:01,540
So here it's now always Submittable
22
00:01:01,540 --> 00:01:02,900
and if I click on Login,
23
00:01:02,900 --> 00:01:06,660
I now want to make sure that we actually focus
24
00:01:06,660 --> 00:01:08,930
the first Input that is invalid.
25
00:01:08,930 --> 00:01:10,990
So in this case that we put the cursor
26
00:01:10,990 --> 00:01:13,450
into the email Input here.
27
00:01:13,450 --> 00:01:15,680
That's something you might want.
28
00:01:15,680 --> 00:01:17,350
So for that, I'll actually turn this
29
00:01:17,350 --> 00:01:20,370
into a else if statement and check if the form is valid,
30
00:01:20,370 --> 00:01:23,910
because the email is not valid
31
00:01:23,910 --> 00:01:26,670
hence the exclamation mark at the beginning,
32
00:01:26,670 --> 00:01:29,520
or else if the email should be valid,
33
00:01:29,520 --> 00:01:32,050
it has to be the password that is invalid
34
00:01:32,050 --> 00:01:34,420
then we'll go into this block.
35
00:01:34,420 --> 00:01:36,380
Of course both could be invalid,
36
00:01:36,380 --> 00:01:38,470
but again, I wanna focus the first one,
37
00:01:38,470 --> 00:01:40,740
which is invalid and the first Input we have
38
00:01:40,740 --> 00:01:43,010
that could be invalid is the email
39
00:01:43,010 --> 00:01:45,320
hence I'm checking this first.
40
00:01:45,320 --> 00:01:48,630
But now the goal is to focus the input
41
00:01:48,630 --> 00:01:50,793
and for a regular input
42
00:01:50,793 --> 00:01:53,970
that would be possible by putting a ref on it.
43
00:01:53,970 --> 00:01:56,570
We learned about refs already in this course
44
00:01:56,570 --> 00:01:58,270
with the useRef hook.
45
00:01:58,270 --> 00:02:01,110
And then we could call the focus method,
46
00:02:01,110 --> 00:02:02,510
just to show this to you,
47
00:02:02,510 --> 00:02:06,380
here in the Input Component where we have the native input,
48
00:02:06,380 --> 00:02:09,009
raw Input HTML Component,
49
00:02:09,009 --> 00:02:14,010
we could use the useRef hook here
50
00:02:14,260 --> 00:02:17,350
to create a inputRef like this
51
00:02:19,310 --> 00:02:21,747
and then for example, if we would want to focus this
52
00:02:21,747 --> 00:02:24,030
after the Component was rendered,
53
00:02:24,030 --> 00:02:27,410
we could use useEffect to run some code
54
00:02:27,410 --> 00:02:29,860
after the Component was rendered.
55
00:02:29,860 --> 00:02:33,060
You learned that the function you parse to useEffect runs
56
00:02:33,060 --> 00:02:35,940
after every Component render cycle.
57
00:02:35,940 --> 00:02:37,820
Let's say we only wanna run it once,
58
00:02:37,820 --> 00:02:39,690
when the Component initially renders
59
00:02:39,690 --> 00:02:42,630
hence I parse an empty array as a dependency array
60
00:02:42,630 --> 00:02:44,970
so that this only runs after the first time
61
00:02:44,970 --> 00:02:48,010
this Component was executed and rendered.
62
00:02:48,010 --> 00:02:51,760
And then here, we could focus the input
63
00:02:51,760 --> 00:02:54,240
by adding the ref prop to the input.
64
00:02:54,240 --> 00:02:58,810
The ref prop is supported on all built-in HTML Components
65
00:02:58,810 --> 00:03:00,760
like Input, for example,
66
00:03:00,760 --> 00:03:02,473
point at inputRef and in useEffect
67
00:03:03,952 --> 00:03:07,283
we could now use inputRef.current.focus.
68
00:03:08,700 --> 00:03:12,600
And the focus method is a method that is available
69
00:03:12,600 --> 00:03:15,430
on the Input DOM object,
70
00:03:15,430 --> 00:03:17,903
to which you got access through this Ref.
71
00:03:18,840 --> 00:03:20,840
So here we're just using Refs
72
00:03:20,840 --> 00:03:23,320
as you learned them early in the course already,
73
00:03:23,320 --> 00:03:25,350
we connected our ref to the input.
74
00:03:25,350 --> 00:03:28,350
And then we use useEffect to focus this input
75
00:03:28,350 --> 00:03:31,000
after this Component rendered.
76
00:03:31,000 --> 00:03:33,330
And as a result, since the Input will render
77
00:03:33,330 --> 00:03:35,460
for both the email and the password,
78
00:03:35,460 --> 00:03:37,950
this will focus the password Input
79
00:03:37,950 --> 00:03:39,100
because that's the second
80
00:03:39,100 --> 00:03:41,560
and therefore last Input that's being rendered.
81
00:03:41,560 --> 00:03:44,510
Hence if this reloads you see the first one
82
00:03:44,510 --> 00:03:48,040
is marked as invalid because it was temporarily focused,
83
00:03:48,040 --> 00:03:51,380
but then the password is the Input that stays focused
84
00:03:51,380 --> 00:03:52,900
at the end.
85
00:03:52,900 --> 00:03:55,070
Now that's not the behavior we want,
86
00:03:55,070 --> 00:03:57,810
but that's something we can do with references
87
00:03:57,810 --> 00:04:00,800
and the built-in functionalities we have in React
88
00:04:00,800 --> 00:04:02,970
and simply in Vanilla JavaScript.
89
00:04:02,970 --> 00:04:06,000
Focus is a method that's not coming from React
90
00:04:06,000 --> 00:04:08,150
but that's built-in to JavaScript,
91
00:04:08,150 --> 00:04:10,090
built into the DOM objects,
92
00:04:10,090 --> 00:04:13,323
the Input DOM object specifically you're dealing with.
93
00:04:14,570 --> 00:04:16,800
Now again, my goal is not to do that
94
00:04:16,800 --> 00:04:18,779
after the Input is rendered though.
95
00:04:18,779 --> 00:04:21,019
So we can remove useEffect.
96
00:04:21,019 --> 00:04:23,230
My goal is that I for example,
97
00:04:23,230 --> 00:04:27,360
have my own method here in the Input Component,
98
00:04:27,360 --> 00:04:29,590
let's say it's called activate,
99
00:04:29,590 --> 00:04:32,240
you could also call it focus, of course.
100
00:04:32,240 --> 00:04:36,040
And in there, I want to use the inputRef.current
101
00:04:36,040 --> 00:04:38,133
and focus my input.
102
00:04:39,010 --> 00:04:42,790
But now to goal is that activate is a function
103
00:04:42,790 --> 00:04:44,950
that's not called from inside the input
104
00:04:44,950 --> 00:04:46,780
but from outside.
105
00:04:46,780 --> 00:04:47,800
Now, I'll say it again,
106
00:04:47,800 --> 00:04:51,970
this is a rare scenario because typically,
107
00:04:51,970 --> 00:04:55,670
you don't wanna code your React projects like this,
108
00:04:55,670 --> 00:04:57,870
instead you wanna work with props and state
109
00:04:57,870 --> 00:05:00,150
and parse data down to a Component
110
00:05:00,150 --> 00:05:01,880
to then change something there.
111
00:05:01,880 --> 00:05:04,570
But in rare cases, like in this example,
112
00:05:04,570 --> 00:05:06,420
it might also be an elegant way
113
00:05:06,420 --> 00:05:08,630
of well, focusing this Input here,
114
00:05:08,630 --> 00:05:13,600
if you could call focus or activate on your Input Component
115
00:05:13,600 --> 00:05:16,570
so that you essentially can use your Input Component,
116
00:05:16,570 --> 00:05:18,260
as you can use to built-in one,
117
00:05:18,260 --> 00:05:21,660
because there you have a focus method as well, right?
118
00:05:21,660 --> 00:05:24,240
So maybe you want one or in our case,
119
00:05:24,240 --> 00:05:28,000
activate function on your own Input Component as well.
120
00:05:28,000 --> 00:05:31,163
So a rare use case, but you could face it at some point.
121
00:05:32,250 --> 00:05:33,900
Now of course, you could think,
122
00:05:33,900 --> 00:05:35,420
well, that shouldn't be too hard.
123
00:05:35,420 --> 00:05:38,950
We go to the Login Component where we have our inputs
124
00:05:38,950 --> 00:05:42,923
and we simply use useRef here as well,
125
00:05:42,923 --> 00:05:46,610
useRef like this, imports the useRef hook.
126
00:05:46,610 --> 00:05:49,040
And then in your Login Component,
127
00:05:49,040 --> 00:05:53,020
you create your emailInputRef for example,
128
00:05:53,020 --> 00:05:57,000
by calling useRef and you create your passwordInputRef
129
00:05:58,240 --> 00:06:01,640
by calling you useRef, oops, useRef
130
00:06:01,640 --> 00:06:03,080
so that you have two references,
131
00:06:03,080 --> 00:06:05,860
one for the email and one for the password input.
132
00:06:05,860 --> 00:06:10,860
And then we simply go down and we add the ref prop here
133
00:06:11,820 --> 00:06:15,500
on the first Input and point at the emailInputRef.
134
00:06:16,810 --> 00:06:19,070
And for the password, we also add ref
135
00:06:19,070 --> 00:06:22,143
and point at the passwordInputRef,
136
00:06:23,640 --> 00:06:25,520
could be as easy as that.
137
00:06:25,520 --> 00:06:27,460
Now, therefore, we have a reference
138
00:06:27,460 --> 00:06:29,010
to our own Components now,
139
00:06:29,010 --> 00:06:32,160
one reference to our Input Component for the email
140
00:06:32,160 --> 00:06:35,380
and one reference to the Input Component for the password.
141
00:06:35,380 --> 00:06:38,800
And therefore in the submitHandler,
142
00:06:38,800 --> 00:06:40,970
if the email is valid,
143
00:06:40,970 --> 00:06:43,260
we can is invalid, excuse me,
144
00:06:43,260 --> 00:06:45,070
if the email is invalid,
145
00:06:45,070 --> 00:06:49,890
we can use the emailInputRef.current and call activate,
146
00:06:49,890 --> 00:06:53,933
which is that function we have in our Input.
147
00:06:55,840 --> 00:06:58,030
And we do the same basically in the else block
148
00:06:58,030 --> 00:07:02,310
but for the passwordInputRef, right?
149
00:07:02,310 --> 00:07:04,010
This something you might wanna do.
150
00:07:05,310 --> 00:07:08,810
Well, if we try this, it will not work though.
151
00:07:08,810 --> 00:07:11,290
If I save this you already see an error here,
152
00:07:11,290 --> 00:07:13,943
function Components cannot be given refs.
153
00:07:15,160 --> 00:07:16,890
So this will not work,
154
00:07:16,890 --> 00:07:20,010
we can't use a ref here.
155
00:07:20,010 --> 00:07:22,470
This is not possible.
156
00:07:22,470 --> 00:07:25,570
And then our Component, the Input Component
157
00:07:25,570 --> 00:07:27,750
of course, also doesn't really do anything
158
00:07:27,750 --> 00:07:29,520
with a ref prop internally.
159
00:07:29,520 --> 00:07:32,920
It doesn't accept a ref prop on its props object.
160
00:07:32,920 --> 00:07:37,250
We're not using props.ref anywhere in there.
161
00:07:37,250 --> 00:07:40,660
But even if we do, ref is also a kind of a reserved word
162
00:07:40,660 --> 00:07:43,480
and yeah, we're getting this warning here for a reason.
163
00:07:43,480 --> 00:07:47,020
So this is not an approach that works like this.
164
00:07:47,020 --> 00:07:48,913
However, we can make it work.
165
00:07:49,860 --> 00:07:52,530
We just need to do two things,
166
00:07:52,530 --> 00:07:54,530
for one, in the Input Component,
167
00:07:54,530 --> 00:07:56,420
we need to import another hook,
168
00:07:56,420 --> 00:07:59,650
and that's the useImperativeHandle hook,
169
00:07:59,650 --> 00:08:02,010
has a strange name, but in the end it is a hook
170
00:08:02,010 --> 00:08:04,300
that allows us to use this Component
171
00:08:04,300 --> 00:08:08,060
or functionalities from inside this Component imperatively,
172
00:08:08,060 --> 00:08:10,110
which simply means not through
173
00:08:10,110 --> 00:08:12,500
the regular state props management,
174
00:08:12,500 --> 00:08:14,630
not by controlling the Component
175
00:08:14,630 --> 00:08:16,890
through state in the parent Component,
176
00:08:16,890 --> 00:08:19,980
but instead by directly calling or manipulating something
177
00:08:19,980 --> 00:08:22,800
in the Component programmatically.
178
00:08:22,800 --> 00:08:26,080
And again, that is something you rarely wanna use
179
00:08:26,080 --> 00:08:27,980
and therefore, you shouldn't use it very often
180
00:08:27,980 --> 00:08:29,660
in your projects as well.
181
00:08:29,660 --> 00:08:31,403
You wanna find an alternative.
182
00:08:32,289 --> 00:08:36,409
Nonetheless here, it actually is a pretty nice solution
183
00:08:36,409 --> 00:08:37,472
for this problem.
184
00:08:38,490 --> 00:08:39,980
And all we need to do is
185
00:08:39,980 --> 00:08:42,970
we need to call useImperativeHandle here
186
00:08:42,970 --> 00:08:45,860
and parse two things to it.
187
00:08:45,860 --> 00:08:47,710
Let's start with the second thing
188
00:08:47,710 --> 00:08:49,970
before I talk about the first parameter.
189
00:08:49,970 --> 00:08:52,730
The second parameter is a function,
190
00:08:52,730 --> 00:08:55,930
a function that should return an object.
191
00:08:55,930 --> 00:08:59,390
And that object will contain all the data
192
00:08:59,390 --> 00:09:02,063
you will be able to use from outside.
193
00:09:02,990 --> 00:09:06,470
So for example here, we could add an activate field
194
00:09:06,470 --> 00:09:08,770
or a focus field, totally up to you,
195
00:09:08,770 --> 00:09:12,640
and then point at the internal function
196
00:09:12,640 --> 00:09:15,347
or the internal variable or whatever it is that
197
00:09:15,347 --> 00:09:19,730
should be accessible from outside through that name.
198
00:09:19,730 --> 00:09:22,880
For example, here, point at activate.
199
00:09:22,880 --> 00:09:25,410
And again, this doesn't have to be focused.
200
00:09:25,410 --> 00:09:28,180
This can be activated or anything else as well.
201
00:09:28,180 --> 00:09:30,250
I'm just using different names here to make it clear
202
00:09:30,250 --> 00:09:32,910
that this activate refers to this function.
203
00:09:32,910 --> 00:09:36,750
And that is the externally available name then.
204
00:09:36,750 --> 00:09:39,410
So this is basically a translation object
205
00:09:39,410 --> 00:09:42,930
between internal functionalities and the outside world,
206
00:09:42,930 --> 00:09:44,233
so the parent Component.
207
00:09:45,250 --> 00:09:47,140
Now, this alone doesn't do the trick though.
208
00:09:47,140 --> 00:09:50,290
We also have this first argument,
209
00:09:50,290 --> 00:09:53,100
which we need to provide to useImperativeHandle.
210
00:09:53,100 --> 00:09:56,080
And that's actually something we also get here
211
00:09:56,080 --> 00:09:59,610
in our Component function argument list,
212
00:09:59,610 --> 00:10:01,360
thus far we always just worked
213
00:10:01,360 --> 00:10:05,200
with props and in 99.9% of cases,
214
00:10:05,200 --> 00:10:07,990
that is all you will need.
215
00:10:07,990 --> 00:10:10,740
However, there technically also is a second argument
216
00:10:10,740 --> 00:10:13,273
you can accept and that's a ref.
217
00:10:14,630 --> 00:10:16,270
Well, that's interesting.
218
00:10:16,270 --> 00:10:17,250
There is a ref,
219
00:10:17,250 --> 00:10:20,530
if a ref should be set from outside,
220
00:10:20,530 --> 00:10:22,400
will also need something else to make sure
221
00:10:22,400 --> 00:10:25,260
that this can be set but this is then available.
222
00:10:25,260 --> 00:10:27,660
So if now the parent Component,
223
00:10:27,660 --> 00:10:29,970
the Login Component adds the ref prop
224
00:10:29,970 --> 00:10:32,040
and binds this to something,
225
00:10:32,040 --> 00:10:37,040
essentially, this here will establish the connection.
226
00:10:37,400 --> 00:10:40,790
This will be part of allowing this binding.
227
00:10:40,790 --> 00:10:42,110
And it's this ref, which we
228
00:10:42,110 --> 00:10:43,860
should parse to useImperativeHandle
229
00:10:45,240 --> 00:10:46,850
Now we're still not there yet.
230
00:10:46,850 --> 00:10:49,070
This alone would not work
231
00:10:49,070 --> 00:10:52,660
In order to enable this second argument here,
232
00:10:52,660 --> 00:10:56,530
we need to export our Component function in a special way.
233
00:10:56,530 --> 00:10:58,950
We need to wrap it with something special
234
00:10:58,950 --> 00:11:00,940
and that's coming from React,
235
00:11:00,940 --> 00:11:02,680
and it's called forwardRef.
236
00:11:04,472 --> 00:11:06,770
And that is basically a function which we execute,
237
00:11:06,770 --> 00:11:08,380
a method which we execute,
238
00:11:08,380 --> 00:11:11,270
to which we parse our Component function.
239
00:11:11,270 --> 00:11:14,030
So our Component function is now the first argument
240
00:11:14,030 --> 00:11:18,670
to forwardRef and forwardRef returns a React Component,
241
00:11:18,670 --> 00:11:21,110
so Input still is a React Component
242
00:11:21,110 --> 00:11:24,660
but a React Component that is capable of
243
00:11:24,660 --> 00:11:26,543
being bound to a ref.
244
00:11:27,380 --> 00:11:29,500
Now, since I wrapped forward ref here,
245
00:11:29,500 --> 00:11:32,760
I of course always need a closing bracket here.
246
00:11:32,760 --> 00:11:33,700
And now with that,
247
00:11:33,700 --> 00:11:38,700
Input is able to take a ref prop
248
00:11:39,370 --> 00:11:41,120
and it will expose a ref,
249
00:11:41,120 --> 00:11:46,040
and it is controllable or usable with refs.
250
00:11:46,040 --> 00:11:48,330
But the only thing you will be able to use
251
00:11:48,330 --> 00:11:52,333
is what you expose here through useImperativeHandle.
252
00:11:53,260 --> 00:11:58,260
So for example, here, I'm exposing this focus function,
253
00:11:58,680 --> 00:12:02,090
a function because it points at the activate function.
254
00:12:02,090 --> 00:12:04,120
So now in the Login Component,
255
00:12:04,120 --> 00:12:07,710
we can call emailInputRef.current.focus
256
00:12:07,710 --> 00:12:10,263
because that's the external name we set up.
257
00:12:11,330 --> 00:12:13,740
And with that, we can save this.
258
00:12:13,740 --> 00:12:15,080
And if I now click Login,
259
00:12:15,080 --> 00:12:17,200
you see the email is selected,
260
00:12:17,200 --> 00:12:19,250
the first invalid input.
261
00:12:19,250 --> 00:12:22,530
If I enter something valid here and I click Login,
262
00:12:22,530 --> 00:12:24,220
you see the password is now selected
263
00:12:24,220 --> 00:12:25,740
because it's invalid
264
00:12:26,980 --> 00:12:30,070
The same here if I click out of it but it's invalid,
265
00:12:30,070 --> 00:12:31,430
it is selected.
266
00:12:31,430 --> 00:12:33,070
And I can of course also still log in
267
00:12:33,070 --> 00:12:34,383
if everything is valid.
268
00:12:35,500 --> 00:12:37,760
So that is a niche use case,
269
00:12:37,760 --> 00:12:41,340
but especially for something like focusing inputs and so on,
270
00:12:41,340 --> 00:12:43,200
this can be very useful.
271
00:12:43,200 --> 00:12:45,650
So this is a very realistic use case,
272
00:12:45,650 --> 00:12:47,480
which I'm showing to you here.
273
00:12:47,480 --> 00:12:49,680
With the useImperativeHandle and forwardRef,
274
00:12:50,980 --> 00:12:55,150
you can expose functionalities from a React Component
275
00:12:55,150 --> 00:12:59,060
to its parent Component to then use your Component
276
00:12:59,060 --> 00:13:01,960
in the parent Component through refs
277
00:13:01,960 --> 00:13:04,660
and trigger certain functionalities.
278
00:13:04,660 --> 00:13:06,250
That is something you can do.
279
00:13:06,250 --> 00:13:08,580
And that does not just work for functions,
280
00:13:08,580 --> 00:13:11,430
we could also expose the value here through refs
281
00:13:11,430 --> 00:13:13,170
if we wanted to.
282
00:13:13,170 --> 00:13:15,380
So this something you can do not something
283
00:13:15,380 --> 00:13:16,690
you will need all the time
284
00:13:16,690 --> 00:13:19,970
and you should avoid it at all costs,
285
00:13:19,970 --> 00:13:21,330
I would almost say,
286
00:13:21,330 --> 00:13:24,160
but especially in cases like this with focusing,
287
00:13:24,160 --> 00:13:25,700
but also in some other use cases
288
00:13:25,700 --> 00:13:27,390
like with scrolling and so on,
289
00:13:27,390 --> 00:13:28,930
this can be very useful
290
00:13:28,930 --> 00:13:31,410
and then triggering something like this programmatically
291
00:13:31,410 --> 00:13:32,390
is fine.
292
00:13:32,390 --> 00:13:35,240
And with useImperativeHhandle and forwardRef,
293
00:13:35,240 --> 00:13:37,053
you are able to make it work.
22804
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.