All language subtitles for 009 Using the useReducer() Hook_en

af Afrikaans
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bn Bengali
bs Bosnian
bg Bulgarian
ca Catalan
ceb Cebuano
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
tl Filipino
fi Finnish
fr French
fy Frisian
gl Galician
ka Georgian
de German
el Greek
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
km Khmer
ko Korean
ku Kurdish (Kurmanji)
ky Kyrgyz
lo Lao
la Latin
lv Latvian
lt Lithuanian
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mn Mongolian
my Myanmar (Burmese)
ne Nepali
no Norwegian
ps Pashto
fa Persian Download
pl Polish
pt Portuguese
pa Punjabi
ro Romanian
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
st Sesotho
sn Shona
sd Sindhi
si Sinhala
sk Slovak
sl Slovenian
so Somali
es Spanish
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
te Telugu
th Thai
tr Turkish
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
or Odia (Oriya)
rw Kinyarwanda
tk Turkmen
tt Tatar
ug Uyghur
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 1 00:00:02,110 --> 00:00:03,090 So with that, we know 2 00:00:03,090 --> 00:00:05,530 when we might wanna use useReducer, 3 00:00:05,530 --> 00:00:06,773 how does it work though? 4 00:00:08,260 --> 00:00:10,760 It looks like this, and that's quite a bit of code. 5 00:00:10,760 --> 00:00:14,710 So let's have a look at this step by step. 6 00:00:14,710 --> 00:00:16,960 useReducer just like useState, 7 00:00:16,960 --> 00:00:20,910 always returns an array with exactly two values. 8 00:00:20,910 --> 00:00:23,810 And therefore you can use array destructuring 9 00:00:23,810 --> 00:00:27,380 as we did it with useState to pull out these values 10 00:00:27,380 --> 00:00:30,010 and store them in separate constants. 11 00:00:30,010 --> 00:00:32,220 Now, the two values you are getting 12 00:00:32,220 --> 00:00:34,660 are the latest state snapshot, 13 00:00:34,660 --> 00:00:37,080 because it is a state management mechanism 14 00:00:37,080 --> 00:00:38,120 like useState. 15 00:00:38,120 --> 00:00:40,453 So of course you get your state snapshot. 16 00:00:41,440 --> 00:00:42,890 But you also get a function 17 00:00:42,890 --> 00:00:46,190 that allows you to update that state snapshot. 18 00:00:46,190 --> 00:00:50,860 So that's kind of the same as for useState, 19 00:00:50,860 --> 00:00:54,800 though the state updating function will work differently. 20 00:00:54,800 --> 00:00:57,630 Instead of just setting a new state value, 21 00:00:57,630 --> 00:01:01,430 you will dispatch an action. 22 00:01:01,430 --> 00:01:04,950 And that action will be consumed by the first argument 23 00:01:04,950 --> 00:01:08,963 you pass to useReducer a so-called reducer function. 24 00:01:09,880 --> 00:01:11,220 So this is a function 25 00:01:11,220 --> 00:01:15,430 which gets the latest state snapshot automatically 26 00:01:15,430 --> 00:01:18,310 because this function will be called by React 27 00:01:18,310 --> 00:01:21,390 and it gets the action that was dispatched. 28 00:01:21,390 --> 00:01:24,380 Because React will call this reducer function 29 00:01:24,380 --> 00:01:26,990 whenever a new action is dispatched. 30 00:01:26,990 --> 00:01:31,000 So then it gets the last state snapshot managed by React. 31 00:01:31,000 --> 00:01:33,410 And that gets the action that was dispatched 32 00:01:33,410 --> 00:01:36,723 that triggered this reducer function execution. 33 00:01:38,070 --> 00:01:39,580 Now the reducer function 34 00:01:39,580 --> 00:01:41,760 then also should do one important thing. 35 00:01:41,760 --> 00:01:45,880 It should return a new updated state. 36 00:01:45,880 --> 00:01:50,050 So it's a bit like the function form of the useState hook, 37 00:01:50,050 --> 00:01:52,470 but an extended version of that, you could say, 38 00:01:52,470 --> 00:01:56,180 because of that action thing, which you'll see in action, 39 00:01:56,180 --> 00:01:58,043 no pun intended, in a second. 40 00:01:59,070 --> 00:02:01,320 In addition, you can also set some initial state 41 00:02:01,320 --> 00:02:04,280 and also an initial function 42 00:02:04,280 --> 00:02:06,470 that should run to set the initial state 43 00:02:06,470 --> 00:02:09,139 in case your initial state is a bit more complex. 44 00:02:09,139 --> 00:02:13,250 And for example, the result of let's say HTTP requests 45 00:02:13,250 --> 00:02:14,580 or anything like that. 46 00:02:14,580 --> 00:02:16,280 We'll ignore that for now. 47 00:02:16,280 --> 00:02:18,240 So that's useReducer in theory. 48 00:02:18,240 --> 00:02:19,390 Let's see it in action. 49 00:02:20,250 --> 00:02:24,570 Now I did mention that we could use useReducer here 50 00:02:24,570 --> 00:02:28,420 to combine our entered values and validities 51 00:02:28,420 --> 00:02:31,050 for the email and the password. 52 00:02:31,050 --> 00:02:33,320 And we could also use it to manage 53 00:02:33,320 --> 00:02:36,290 the overall form state with it. 54 00:02:36,290 --> 00:02:39,330 So we could either manage one big form state 55 00:02:39,330 --> 00:02:43,410 that includes everything or in multiple smaller states. 56 00:02:43,410 --> 00:02:46,340 Both would work, both would be fine, 57 00:02:46,340 --> 00:02:48,820 but to keep things simple here, 58 00:02:48,820 --> 00:02:52,590 we will simply start by managing our emailState 59 00:02:52,590 --> 00:02:54,673 with useReducer. 60 00:02:54,673 --> 00:02:57,550 And desired goal is to combine the value 61 00:02:57,550 --> 00:03:01,963 and the validity into one state managed by useReducer. 62 00:03:03,800 --> 00:03:08,163 First of all, we need to import useReducer here. 63 00:03:10,090 --> 00:03:12,970 And we then call it for example here. 64 00:03:12,970 --> 00:03:16,040 And useReducer, as you learned returns an array 65 00:03:16,040 --> 00:03:17,490 with exactly two elements, 66 00:03:17,490 --> 00:03:19,060 and we can use array destructuring 67 00:03:19,060 --> 00:03:20,743 to pull those elements out of it. 68 00:03:21,750 --> 00:03:24,260 Now I'm going to useReducer for my email 69 00:03:24,260 --> 00:03:25,930 and my password separately. 70 00:03:25,930 --> 00:03:28,950 You could also merge this all into one big reducer 71 00:03:28,950 --> 00:03:30,790 and here we therefore get back, 72 00:03:30,790 --> 00:03:34,790 let's say the emailState and our dispatch function. 73 00:03:34,790 --> 00:03:36,623 I'll name it, dispatchEmail. 74 00:03:37,860 --> 00:03:39,773 These names are up to you, of course. 75 00:03:41,030 --> 00:03:44,030 Then I mentioned that useReducer as a first argument 76 00:03:44,030 --> 00:03:45,470 takes a function. 77 00:03:45,470 --> 00:03:48,160 Here again, I'm using an anonymous function. 78 00:03:48,160 --> 00:03:50,530 Though we actually could also outsource this 79 00:03:50,530 --> 00:03:52,460 into a separate named function, 80 00:03:52,460 --> 00:03:54,850 maybe to make this easier to read. 81 00:03:54,850 --> 00:03:56,653 And I'll name this emailReducer 82 00:03:57,840 --> 00:03:59,700 and I'll store my function, 83 00:03:59,700 --> 00:04:01,850 my arrow function in this constant 84 00:04:01,850 --> 00:04:04,333 so that I can point at email reducer here. 85 00:04:05,200 --> 00:04:09,440 Now, please note that I created this reducer function 86 00:04:09,440 --> 00:04:12,070 outside of the component function. 87 00:04:12,070 --> 00:04:16,750 And I did so because inside of this reducer function, 88 00:04:16,750 --> 00:04:18,519 we won't need any data 89 00:04:18,519 --> 00:04:21,630 that's generated inside of the component function. 90 00:04:21,630 --> 00:04:26,630 So this reducer function can be created outside of the scope 91 00:04:27,080 --> 00:04:28,970 of this component function 92 00:04:28,970 --> 00:04:32,250 because it doesn't need to interact with anything 93 00:04:32,250 --> 00:04:35,430 defined inside of the component function. 94 00:04:35,430 --> 00:04:38,230 All the data which will be required 95 00:04:38,230 --> 00:04:41,320 and used inside of the reducer function 96 00:04:41,320 --> 00:04:44,180 will be passed into this function 97 00:04:44,180 --> 00:04:48,180 when it's executed by React, automatically. 98 00:04:48,180 --> 00:04:50,220 So that's why we can define it 99 00:04:50,220 --> 00:04:53,100 outside off the component function here. 100 00:04:53,100 --> 00:04:56,120 Now this reducer function receives two arguments, 101 00:04:56,120 --> 00:04:57,470 two parameters. 102 00:04:57,470 --> 00:05:02,470 Our last state snapshot and the action that was dispatched. 103 00:05:03,210 --> 00:05:06,730 And you'll see what this action is in just a second. 104 00:05:06,730 --> 00:05:08,900 And we should return a new state. 105 00:05:08,900 --> 00:05:11,510 Now here, our state could be an object 106 00:05:11,510 --> 00:05:14,860 where we have the value, which is initially an empty string. 107 00:05:14,860 --> 00:05:18,040 And let's say the isValid field, which initially is false, 108 00:05:18,040 --> 00:05:18,913 for example. 109 00:05:20,660 --> 00:05:22,830 That also could be our initial state here 110 00:05:22,830 --> 00:05:24,160 which is the second argument 111 00:05:24,160 --> 00:05:29,040 we passed to useReducer value and isValid to false. 112 00:05:29,040 --> 00:05:31,100 That's the initial state we set here 113 00:05:31,100 --> 00:05:32,993 for our emailState snapshot. 114 00:05:34,600 --> 00:05:38,633 Now the emailState is therefore what we can use in our code. 115 00:05:41,070 --> 00:05:44,980 For example here, where I want the entered email. 116 00:05:44,980 --> 00:05:47,290 Now that's emailState.value 117 00:05:47,290 --> 00:05:49,700 because that's where we're going to store it. 118 00:05:49,700 --> 00:05:51,290 The entered value. 119 00:05:51,290 --> 00:05:54,790 We don't have to code for that yet, but soon we will. 120 00:05:54,790 --> 00:05:56,820 So that's where we could access this. 121 00:05:56,820 --> 00:06:01,210 Also here, emailState.value.includes('@'). 122 00:06:01,210 --> 00:06:02,840 But actually keep in mind 123 00:06:02,840 --> 00:06:05,770 that we have the isValid field in there 124 00:06:05,770 --> 00:06:09,400 and we're going to add code that changes it eventually soon. 125 00:06:09,400 --> 00:06:12,490 So instead of revalidating here, 126 00:06:12,490 --> 00:06:17,300 we could also just check if emailState isValid is true, 127 00:06:17,300 --> 00:06:19,774 and therefore we can simplify this here, 128 00:06:19,774 --> 00:06:23,386 emailState isValid. 129 00:06:23,386 --> 00:06:25,820 And if we scroll down further here in the submit handler, 130 00:06:25,820 --> 00:06:28,150 here we wanna forward the value. 131 00:06:28,150 --> 00:06:31,283 So that would be emailState.value. 132 00:06:32,800 --> 00:06:35,083 And then the JSX code, of course, 133 00:06:36,100 --> 00:06:38,190 instead of email isValid, 134 00:06:38,190 --> 00:06:40,733 we have emailState isValid. 135 00:06:43,180 --> 00:06:46,830 And here where I pass the value back into the input, 136 00:06:46,830 --> 00:06:48,843 we have emailState.value, 137 00:06:51,421 --> 00:06:53,910 and that should be the different places 138 00:06:53,910 --> 00:06:56,463 where I'm using my email states. 139 00:06:57,360 --> 00:07:00,970 With that, entered email and email isValid 140 00:07:00,970 --> 00:07:02,900 should now be gray because we're not using them 141 00:07:02,900 --> 00:07:04,830 anywhere in our code anymore. 142 00:07:04,830 --> 00:07:07,570 So we can remove these to useState calls here, 143 00:07:07,570 --> 00:07:08,840 and I will comment them out 144 00:07:08,840 --> 00:07:10,620 so that we still see this alternative, 145 00:07:10,620 --> 00:07:12,720 but we're not using it anymore. 146 00:07:12,720 --> 00:07:14,330 But we're not done with the reducer. 147 00:07:14,330 --> 00:07:16,590 Right now, it always returns to this state, 148 00:07:16,590 --> 00:07:18,390 which of course is not what we want. 149 00:07:19,370 --> 00:07:22,510 Instead, we need to dispatch an action eventually. 150 00:07:22,510 --> 00:07:24,730 We need to dispatch it here, for example, 151 00:07:24,730 --> 00:07:26,830 when we want to update the value, 152 00:07:26,830 --> 00:07:29,833 or here, when we want to update the validity. 153 00:07:31,140 --> 00:07:32,820 Now let's start with the value. 154 00:07:32,820 --> 00:07:36,270 Here we now update this by calling dispatchEmail 155 00:07:36,270 --> 00:07:39,070 and we pass to it as so-called action. 156 00:07:39,070 --> 00:07:41,220 Now it's totally up to you 157 00:07:41,220 --> 00:07:43,060 what this action is. 158 00:07:43,060 --> 00:07:44,950 It can be a string identifier, 159 00:07:44,950 --> 00:07:47,297 something like NEW_EMAIL_VALUE. 160 00:07:49,739 --> 00:07:51,090 It could be a number, 161 00:07:51,090 --> 00:07:53,260 but often will be an object 162 00:07:53,260 --> 00:07:56,870 which has some field that holds some identifier 163 00:07:56,870 --> 00:07:59,540 often the field is then named type. 164 00:07:59,540 --> 00:08:04,540 And that could be something like USER_INPUT, for example. 165 00:08:04,800 --> 00:08:06,690 Now it doesn't have to be all caps. 166 00:08:06,690 --> 00:08:09,110 That's just a convention you see a lot. 167 00:08:09,110 --> 00:08:10,620 So a string, all caps, 168 00:08:10,620 --> 00:08:14,710 with some clearly understandable identifier. 169 00:08:14,710 --> 00:08:19,290 And then we also can add an extra payload to this action. 170 00:08:19,290 --> 00:08:22,200 Again, I'm saying you can, because it's up to you, 171 00:08:22,200 --> 00:08:24,853 but here, since we wanna save what the user entered, 172 00:08:25,900 --> 00:08:28,350 it would make sense to add some payload. 173 00:08:28,350 --> 00:08:30,430 So for example, a val field 174 00:08:30,430 --> 00:08:33,673 that holds the event target value. 175 00:08:34,559 --> 00:08:35,960 So now that's our action. 176 00:08:35,960 --> 00:08:38,690 It's this object with a type field 177 00:08:38,690 --> 00:08:43,070 that describes what happened and extra payload in this case, 178 00:08:43,070 --> 00:08:44,733 the value the user entered. 179 00:08:48,510 --> 00:08:52,070 So this now will trigger this function here to execute 180 00:08:52,070 --> 00:08:55,880 because that's the reducer function we passed to useReducer. 181 00:08:56,850 --> 00:08:58,610 Now here we can handle this action, 182 00:08:58,610 --> 00:09:00,670 for example, with the if statement. 183 00:09:00,670 --> 00:09:04,563 We can check if action.type is equal to user input. 184 00:09:05,710 --> 00:09:10,110 Keep in mind, what we dispatch as action will be an object 185 00:09:10,110 --> 00:09:12,233 because that's what we set it to here. 186 00:09:13,200 --> 00:09:16,050 And this object happens to have a type field 187 00:09:16,050 --> 00:09:18,560 so I can check for action.type here 188 00:09:18,560 --> 00:09:21,610 and check if the values stored in that type field 189 00:09:21,610 --> 00:09:24,433 is that string with the content user input. 190 00:09:25,290 --> 00:09:27,030 And if that's the case, we could say, 191 00:09:27,030 --> 00:09:31,350 now then I don't want to return this empty state snapshot. 192 00:09:31,350 --> 00:09:35,420 Instead, I want to return the state snapshot for my email, 193 00:09:35,420 --> 00:09:38,490 where the value is action.val. 194 00:09:38,490 --> 00:09:41,463 That's the payload we appended to our action. 195 00:09:42,550 --> 00:09:45,230 And maybe we also want to update the validity here, 196 00:09:45,230 --> 00:09:46,820 if we're already added. 197 00:09:46,820 --> 00:09:49,683 Simply by, for example, checking if action valid, 198 00:09:51,710 --> 00:09:53,660 and then the same logic as down there, 199 00:09:53,660 --> 00:09:57,890 includes the @ symbol for this very trivial validation. 200 00:09:57,890 --> 00:10:00,970 So here I'm then updating both the value 201 00:10:00,970 --> 00:10:05,490 and isValid whenever I received as user input action. 202 00:10:05,490 --> 00:10:09,000 And for any other action that might reach this reducer, 203 00:10:09,000 --> 00:10:10,843 this default state will be returned. 204 00:10:12,860 --> 00:10:15,800 Now we also need to dispatch an action here 205 00:10:15,800 --> 00:10:17,573 on the validate email handler. 206 00:10:18,500 --> 00:10:21,330 So instead of setting the email as valid here, 207 00:10:21,330 --> 00:10:22,713 I can dispatch, 208 00:10:25,100 --> 00:10:26,390 email again. 209 00:10:26,390 --> 00:10:28,070 Again, passing an object. 210 00:10:28,070 --> 00:10:29,590 You should be consistent. 211 00:10:29,590 --> 00:10:32,480 Your actions should always have the same structure, 212 00:10:32,480 --> 00:10:33,940 so that your code, where you, 213 00:10:33,940 --> 00:10:36,970 for example, try to access a type property 214 00:10:36,970 --> 00:10:38,960 does not suddenly fail. 215 00:10:38,960 --> 00:10:41,650 So once you've decided for an action structure, 216 00:10:41,650 --> 00:10:43,440 you wanna stick to it. 217 00:10:43,440 --> 00:10:46,530 Therefore, here I, again, dispatch an object 218 00:10:46,530 --> 00:10:47,820 with a type field. 219 00:10:47,820 --> 00:10:49,630 Now here it's for example, 220 00:10:49,630 --> 00:10:53,350 input blur, because the input lost focus, 221 00:10:53,350 --> 00:10:54,423 it was blurred. 222 00:10:55,690 --> 00:10:58,770 And we don't need to add a value here necessarily 223 00:10:58,770 --> 00:11:01,080 because all we care about here 224 00:11:01,080 --> 00:11:03,300 is that the input lost focus. 225 00:11:03,300 --> 00:11:06,270 There is no extra data that needs to be added. 226 00:11:06,270 --> 00:11:08,630 So here we have a simpler action. 227 00:11:08,630 --> 00:11:11,800 So still an object, still with a type property, 228 00:11:11,800 --> 00:11:13,083 but without a value. 229 00:11:14,240 --> 00:11:16,980 The fact that the val is missing does not matter 230 00:11:16,980 --> 00:11:18,880 because this line here, 231 00:11:18,880 --> 00:11:20,760 where we try to access the value, 232 00:11:20,760 --> 00:11:25,543 will not run for action of type input blur. 233 00:11:26,380 --> 00:11:29,403 Because we only run this if the action type is user input. 234 00:11:31,500 --> 00:11:36,093 Instead I will check if the action type is input blur. 235 00:11:37,220 --> 00:11:42,070 And if it is, I wanna return a new snapshot, 236 00:11:42,070 --> 00:11:44,700 a new state value for my emailState. 237 00:11:44,700 --> 00:11:46,300 But now the value of course 238 00:11:46,300 --> 00:11:48,570 should be the value we had before. 239 00:11:48,570 --> 00:11:50,670 I don't wanna reset this to be empty 240 00:11:50,670 --> 00:11:52,890 because the input could blur 241 00:11:52,890 --> 00:11:54,290 after the user entered something. 242 00:11:54,290 --> 00:11:56,120 I don't wanna lose that. 243 00:11:56,120 --> 00:11:58,820 So therefore I'll use my last state snapshot, 244 00:11:58,820 --> 00:12:00,030 which I get here. 245 00:12:00,030 --> 00:12:01,610 And that this is guaranteed 246 00:12:01,610 --> 00:12:04,770 to be the absolute last state snapshot. 247 00:12:04,770 --> 00:12:06,910 React gives us this state snapshot 248 00:12:06,910 --> 00:12:09,060 and it makes sure that it's the latest one. 249 00:12:09,900 --> 00:12:13,770 So here we can safely access state.value, for example, 250 00:12:13,770 --> 00:12:17,400 to access the last value that was entered for the email. 251 00:12:17,400 --> 00:12:19,210 And for the validity, we can there for check 252 00:12:19,210 --> 00:12:21,710 if the state value is valid, 253 00:12:21,710 --> 00:12:24,783 by again, repeating our validity check here. 254 00:12:25,760 --> 00:12:27,940 And of course you could always refactor this check 255 00:12:27,940 --> 00:12:29,100 into a function, 256 00:12:29,100 --> 00:12:31,713 but I don't want to make this overly complicated. 257 00:12:32,720 --> 00:12:35,330 So with this, we now have this extra action. 258 00:12:35,330 --> 00:12:38,740 And as a result, if I log out here, 259 00:12:38,740 --> 00:12:43,330 you see initially it's blurred, which makes sense actually, 260 00:12:43,330 --> 00:12:48,330 because my initial value for isValid is false. 261 00:12:48,620 --> 00:12:51,713 If I set this to undefined or to null instead, 262 00:12:52,840 --> 00:12:55,000 you'll see it's not treated as invalid. 263 00:12:55,000 --> 00:12:58,740 It's not treated as if it was blurred from the beginning on. 264 00:12:58,740 --> 00:13:00,410 But if I click in there it is. 265 00:13:00,410 --> 00:13:04,310 And if I then start typing, I'm getting an error. 266 00:13:04,310 --> 00:13:07,290 Cannot read property 'includes' of undefined. 267 00:13:07,290 --> 00:13:08,840 And what could be causing that? 268 00:13:10,440 --> 00:13:13,040 Well, it looks like we're having problems 269 00:13:13,040 --> 00:13:14,770 running this code here, 270 00:13:14,770 --> 00:13:18,510 because that clearly has to be the action that triggered. 271 00:13:18,510 --> 00:13:21,540 And that's simply because here I'm checking action.valid. 272 00:13:21,540 --> 00:13:23,970 Of course it should be action.val. 273 00:13:23,970 --> 00:13:26,150 So the value I'm retrieving here. 274 00:13:26,150 --> 00:13:28,820 So a simple typo here, my mistake. 275 00:13:28,820 --> 00:13:29,850 Let's reload. 276 00:13:29,850 --> 00:13:31,170 Now I can type here. 277 00:13:31,170 --> 00:13:32,470 And then that all seems to work. 278 00:13:32,470 --> 00:13:36,030 And overall, this works as before, 279 00:13:36,030 --> 00:13:39,130 without the debouncing, because I commented out that code, 280 00:13:39,130 --> 00:13:41,590 but the general form validation works, 281 00:13:41,590 --> 00:13:43,343 now with the help of useReducer. 282 00:13:44,280 --> 00:13:47,290 And this allows us to group this emailState together 283 00:13:47,290 --> 00:13:50,070 and manage it in one place. 284 00:13:50,070 --> 00:13:52,550 It's a little bit more set up up here, 285 00:13:52,550 --> 00:13:54,650 but on the other hand, the code in the component 286 00:13:54,650 --> 00:13:58,050 then is simpler because there, we only need to dispatch 287 00:13:58,050 --> 00:14:01,263 and not do any validation or anything like that. 288 00:14:02,350 --> 00:14:04,590 So here's a task for you now. 289 00:14:04,590 --> 00:14:05,677 Take this. 290 00:14:05,677 --> 00:14:07,990 How do you find the finish code snapshot, 291 00:14:07,990 --> 00:14:10,323 and do the same for the password. 22789

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.