1 00:00:00,000 --> 00:00:03,402 [MUSIC PLAYING] 2 00:00:03,402 --> 00:00:16,530 3 00:00:16,530 --> 00:00:18,330 SPEAKER 1: Hello and welcome for Lecture 5. 4 00:00:18,330 --> 00:00:21,090 This week we'll be talking about user input, which we discussed 5 00:00:21,090 --> 00:00:23,891 a bit last week, and debugging. 6 00:00:23,891 --> 00:00:26,640 So in the previous lecture, we discussed a few different concepts. 7 00:00:26,640 --> 00:00:31,260 We talked about scrolling views, which are the views where you can scroll. 8 00:00:31,260 --> 00:00:35,310 The caveat to that being that all of its children render before the whole view 9 00:00:35,310 --> 00:00:36,210 renders. 10 00:00:36,210 --> 00:00:41,160 We talked about a couple virtualized lists, flat list and section list. 11 00:00:41,160 --> 00:00:45,000 Those are the couple lists where they're much more performant because they'll 12 00:00:45,000 --> 00:00:46,624 only render what's in view. 13 00:00:46,624 --> 00:00:48,540 The difference being that section lists allows 14 00:00:48,540 --> 00:00:51,420 you to separate your data into different separate sections 15 00:00:51,420 --> 00:00:54,060 and have a section header to go along with those. 16 00:00:54,060 --> 00:00:56,360 We then started to talk about user input. 17 00:00:56,360 --> 00:00:59,610 We talked about the difference between controlled and uncontrolled components. 18 00:00:59,610 --> 00:01:01,980 Controlled components being those components 19 00:01:01,980 --> 00:01:06,510 that track state and the source of truth for the input's values 20 00:01:06,510 --> 00:01:08,440 are on the component state itself. 21 00:01:08,440 --> 00:01:13,530 Whereas uncontrolled components are those where the Dom, or in the case 22 00:01:13,530 --> 00:01:18,269 of the browser, the browser itself keeps track of those input's values. 23 00:01:18,269 --> 00:01:20,310 We then talked about text input for a little bit, 24 00:01:20,310 --> 00:01:26,460 which was the component used to accept user input. 25 00:01:26,460 --> 00:01:29,952 And first, we'll talk about user input today. 26 00:01:29,952 --> 00:01:31,660 And so we talked briefly about controlled 27 00:01:31,660 --> 00:01:34,650 versus uncontrolled components. 28 00:01:34,650 --> 00:01:39,845 And how for React native, you need to use controlled components. 29 00:01:39,845 --> 00:01:41,970 React recommends always using controlled components 30 00:01:41,970 --> 00:01:44,680 even when using React web as well. 31 00:01:44,680 --> 00:01:48,000 And so we looked at how user inputs take a couple of different props. 32 00:01:48,000 --> 00:01:53,820 One value which dictates what the value, or what displays inside the text box, 33 00:01:53,820 --> 00:01:54,567 is. 34 00:01:54,567 --> 00:01:57,150 And then unchanged text, which is the callback that is invoked 35 00:01:57,150 --> 00:02:01,610 every time you change that value. 36 00:02:01,610 --> 00:02:04,330 And so the docs are linked in the lecture slides. 37 00:02:04,330 --> 00:02:08,919 And so let's take a look at the example that we were looking at last week. 38 00:02:08,919 --> 00:02:11,460 So last week we were writing this application 39 00:02:11,460 --> 00:02:17,300 where we have a section list here. 40 00:02:17,300 --> 00:02:21,810 And then we are starting to add a screen where we can add contacts to that list. 41 00:02:21,810 --> 00:02:27,540 And so, where we left off last week, we could type into the name here. 42 00:02:27,540 --> 00:02:30,300 We could type into the phone here. 43 00:02:30,300 --> 00:02:32,400 But nothing actually happens with those values. 44 00:02:32,400 --> 00:02:34,490 And when we click submit, nothing happens. 45 00:02:34,490 --> 00:02:36,620 Let's build out the rest of that app this week. 46 00:02:36,620 --> 00:02:39,850 47 00:02:39,850 --> 00:02:47,180 So in add contact form, when we left off last week, we had a few things written. 48 00:02:47,180 --> 00:02:52,170 So we kept track of the name and the phone number and state. 49 00:02:52,170 --> 00:02:54,410 Let's actually to get rid of that line here. 50 00:02:54,410 --> 00:02:57,067 51 00:02:57,067 --> 00:02:58,900 So we kept track of name and phone and state 52 00:02:58,900 --> 00:03:00,720 since we're using controlled components. 53 00:03:00,720 --> 00:03:06,410 The component itself has to track the value of those texts. 54 00:03:06,410 --> 00:03:08,360 We wrote two separate handlers. 55 00:03:08,360 --> 00:03:12,200 One called handle name change, which takes a name. 56 00:03:12,200 --> 00:03:16,130 Which is fired when you change the text and put down here. 57 00:03:16,130 --> 00:03:20,180 And then it just sets the state so that the name, the key name, 58 00:03:20,180 --> 00:03:22,210 is equal to whatever value is passed in. 59 00:03:22,210 --> 00:03:25,940 And so that, when passed a string, will just update a state value for name. 60 00:03:25,940 --> 00:03:28,430 We have the same function down here but for phone. 61 00:03:28,430 --> 00:03:31,130 And so when you pass in a new phone number down here, 62 00:03:31,130 --> 00:03:35,120 it will just set the state such that the new phone is equal to whatever string 63 00:03:35,120 --> 00:03:36,680 you pass in. 64 00:03:36,680 --> 00:03:42,080 And then the render function, we just define those two text inputs. 65 00:03:42,080 --> 00:03:45,770 So one has a value of this dot state dot name. 66 00:03:45,770 --> 00:03:49,010 And so every time we change the this dot state dot name, 67 00:03:49,010 --> 00:03:51,770 the value's then reflected in this text input. 68 00:03:51,770 --> 00:03:55,160 We set its unchanged text prop to equal that handle name change 69 00:03:55,160 --> 00:03:57,210 function that we defined above. 70 00:03:57,210 --> 00:03:59,270 And then just as a placeholder, we wrote name. 71 00:03:59,270 --> 00:04:01,910 So that when the field is blank, the user 72 00:04:01,910 --> 00:04:05,060 just knows what they're supposed to type in there. 73 00:04:05,060 --> 00:04:08,460 And then we have the same text input down here for phone. 74 00:04:08,460 --> 00:04:10,460 With the one difference being the keyboard type. 75 00:04:10,460 --> 00:04:14,780 And so we don't really want the users to be able to type letters 76 00:04:14,780 --> 00:04:16,459 into the text input. 77 00:04:16,459 --> 00:04:19,610 And so we said what kind of keyboard should pop up. 78 00:04:19,610 --> 00:04:21,200 Only that numeric one. 79 00:04:21,200 --> 00:04:27,470 And so, as we see in our app, when we click on the text input here, 80 00:04:27,470 --> 00:04:29,470 we only see the numbers. 81 00:04:29,470 --> 00:04:34,610 82 00:04:34,610 --> 00:04:37,720 And so now we have a page that is actually handling multiple inputs. 83 00:04:37,720 --> 00:04:41,820 And so the way we handle that in web is we have a form component. 84 00:04:41,820 --> 00:04:45,580 And so that form component in HTML takes the on submit handler 85 00:04:45,580 --> 00:04:49,990 and when you submit the form, that gets invoked. 86 00:04:49,990 --> 00:04:53,137 Unfortunately that does not exist in React native. 87 00:04:53,137 --> 00:04:54,970 But since we're using controlled components, 88 00:04:54,970 --> 00:04:58,340 we actually maintain an object with all of the form data. 89 00:04:58,340 --> 00:05:01,550 So, again, this form component does not exist. 90 00:05:01,550 --> 00:05:05,470 But the analogy is that, for whatever component that we're writing, 91 00:05:05,470 --> 00:05:08,070 all of the information that we need is tracked in the state. 92 00:05:08,070 --> 00:05:11,350 And so we're actually maintaining an object with all of that, 93 00:05:11,350 --> 00:05:12,955 all those input's values. 94 00:05:12,955 --> 00:05:15,580 And so what we can actually do is we can define a function that 95 00:05:15,580 --> 00:05:17,110 handles the data to submit. 96 00:05:17,110 --> 00:05:21,960 And so that would be the analogy to the onsubmit handler in web. 97 00:05:21,960 --> 00:05:25,590 And so let's go ahead and do that in our example. 98 00:05:25,590 --> 00:05:28,990 And so here when we click submit, nothing actually happens. 99 00:05:28,990 --> 00:05:30,490 But what do we want to happen here? 100 00:05:30,490 --> 00:05:35,290 Well, when you click submit, ideally this form gets submitted 101 00:05:35,290 --> 00:05:37,450 and we add a contact. 102 00:05:37,450 --> 00:05:40,260 And so here, we already have a button called submit, 103 00:05:40,260 --> 00:05:43,180 but we haven't said what it should do when we press it. 104 00:05:43,180 --> 00:05:44,600 And so let's define an on press. 105 00:05:44,600 --> 00:05:50,740 106 00:05:50,740 --> 00:05:54,000 And so on press is going to invoke this function called handle submit, 107 00:05:54,000 --> 00:05:55,442 which we have not yet defined. 108 00:05:55,442 --> 00:05:57,150 And let's go ahead and define it up here. 109 00:05:57,150 --> 00:06:03,710 110 00:06:03,710 --> 00:06:07,760 So, as you recall, when you press a button the on press handler 111 00:06:07,760 --> 00:06:09,200 gets invoked with no arguments. 112 00:06:09,200 --> 00:06:12,200 And so we're going to actually have to decide 113 00:06:12,200 --> 00:06:13,670 what to do here with no arguments. 114 00:06:13,670 --> 00:06:19,370 And so we should go ahead and do this dot props because since this 115 00:06:19,370 --> 00:06:23,060 is just generic add contact form, we're not defining the logic 116 00:06:23,060 --> 00:06:24,230 on adding the contact here. 117 00:06:24,230 --> 00:06:26,460 We're just going to define the form here. 118 00:06:26,460 --> 00:06:30,340 And so we're going to assume that a prop called, 119 00:06:30,340 --> 00:06:34,830 let's just call it on submit exists. 120 00:06:34,830 --> 00:06:37,250 And we're going to pass in an object with the state 121 00:06:37,250 --> 00:06:39,900 fields that are necessary. 122 00:06:39,900 --> 00:06:45,800 And so we could do something like name is this dot state dot name. 123 00:06:45,800 --> 00:06:48,520 And phone is this dot state dot phone. 124 00:06:48,520 --> 00:06:52,490 125 00:06:52,490 --> 00:06:55,490 Or the shorthand for here, since we're using every single key value 126 00:06:55,490 --> 00:07:00,140 pair of this dot state, we can actually just do 127 00:07:00,140 --> 00:07:06,125 this dot dot dot, this dot state. 128 00:07:06,125 --> 00:07:09,350 Which means, take all of the key value pairs of this dot state, 129 00:07:09,350 --> 00:07:13,790 and create a new object with those key value pairs. 130 00:07:13,790 --> 00:07:21,000 Or simply, we could just pass this dot state. 131 00:07:21,000 --> 00:07:24,590 And so we're going to invoke this dot props to on submit with this dot state. 132 00:07:24,590 --> 00:07:28,540 And so now we have to define, what are we actually doing on submit. 133 00:07:28,540 --> 00:07:34,430 134 00:07:34,430 --> 00:07:36,140 So let's take a look at AppJS. 135 00:07:36,140 --> 00:07:40,140 So here is a lot of stuff that we wrote last week. 136 00:07:40,140 --> 00:07:43,640 But we have not actually written the way to add a contact. 137 00:07:43,640 --> 00:07:45,690 And so let's go ahead and implement that here. 138 00:07:45,690 --> 00:07:51,800 139 00:07:51,800 --> 00:07:53,330 So this should take an argument. 140 00:07:53,330 --> 00:07:55,621 So we need to know exactly what conduct we want to add. 141 00:07:55,621 --> 00:08:02,329 142 00:08:02,329 --> 00:08:04,620 So it takes a new contact, and what are we going to do? 143 00:08:04,620 --> 00:08:07,450 Well, we should take the previous contacts and append to that. 144 00:08:07,450 --> 00:08:19,190 145 00:08:19,190 --> 00:08:22,650 And since we rely on the value in the previous state, 146 00:08:22,650 --> 00:08:25,230 we should define a function that takes the previous state 147 00:08:25,230 --> 00:08:30,595 and returns a new state, where the new contacts are the old contacts. 148 00:08:30,595 --> 00:08:37,574 149 00:08:37,574 --> 00:08:38,615 And then the new contact. 150 00:08:38,615 --> 00:08:43,179 151 00:08:43,179 --> 00:08:45,510 And so, again, that dot dot dot notation with arrays 152 00:08:45,510 --> 00:08:49,770 means take all of those array values and stick them in this new array. 153 00:08:49,770 --> 00:08:53,030 And then last, add new contact. 154 00:08:53,030 --> 00:08:56,550 So now this function should take a new contact 155 00:08:56,550 --> 00:08:58,890 and set the state such that the contacts are 156 00:08:58,890 --> 00:09:01,980 equal to the old contacts with a new contact appended at the end. 157 00:09:01,980 --> 00:09:04,680 158 00:09:04,680 --> 00:09:10,830 Lastly, we need to pass that handler down to the add contact form here. 159 00:09:10,830 --> 00:09:12,720 So we call it on submit. 160 00:09:12,720 --> 00:09:14,200 And what should it do on submit? 161 00:09:14,200 --> 00:09:16,240 Well it should invoke this dot add contact. 162 00:09:16,240 --> 00:09:19,600 163 00:09:19,600 --> 00:09:22,507 Which will invoke that function that we defined up there. 164 00:09:22,507 --> 00:09:23,840 So let's go ahead and test that. 165 00:09:23,840 --> 00:09:26,870 166 00:09:26,870 --> 00:09:28,210 So now we can go ahead. 167 00:09:28,210 --> 00:09:36,852 Actually let's first just have only one to begin with so it's easy to see. 168 00:09:36,852 --> 00:09:38,780 Let's go ahead and add a contact. 169 00:09:38,780 --> 00:09:40,630 Let's call him my name. 170 00:09:40,630 --> 00:09:45,381 171 00:09:45,381 --> 00:09:47,130 And let's put some random phone number in. 172 00:09:47,130 --> 00:09:51,520 173 00:09:51,520 --> 00:09:52,240 So what happened? 174 00:09:52,240 --> 00:09:56,020 I click submit, but nothing actually happened. 175 00:09:56,020 --> 00:09:57,730 Does anybody see what the bug is here? 176 00:09:57,730 --> 00:10:01,080 177 00:10:01,080 --> 00:10:04,084 So first, how are we determining whether or not 178 00:10:04,084 --> 00:10:05,750 we should display that add contact form? 179 00:10:05,750 --> 00:10:09,180 180 00:10:09,180 --> 00:10:12,840 Well here it says, if the state says, is telling me to show the form, 181 00:10:12,840 --> 00:10:14,870 then I should show the form. 182 00:10:14,870 --> 00:10:17,920 Where do we change that? 183 00:10:17,920 --> 00:10:21,200 Well we have a function that says show the form, 184 00:10:21,200 --> 00:10:26,720 but there's nowhere in any logic do we say, oh now it's time to hide the form. 185 00:10:26,720 --> 00:10:29,740 So where might we want to do that? 186 00:10:29,740 --> 00:10:30,755 Anyone? 187 00:10:30,755 --> 00:10:33,545 In the add contacts? 188 00:10:33,545 --> 00:10:36,000 Yeah, In the add contact function. 189 00:10:36,000 --> 00:10:38,550 So when we add a new contact, we no longer 190 00:10:38,550 --> 00:10:40,320 really need to show that form, right? 191 00:10:40,320 --> 00:10:44,760 And so we can say, update the contacts to the new contacts. 192 00:10:44,760 --> 00:10:47,699 And also say, we don't need to show the form anymore. 193 00:10:47,699 --> 00:10:52,750 194 00:10:52,750 --> 00:11:01,680 And so now when we add a contact, the form hides. 195 00:11:01,680 --> 00:11:05,922 And that contact gets added to our application. 196 00:11:05,922 --> 00:11:10,050 197 00:11:10,050 --> 00:11:10,550 Cool. 198 00:11:10,550 --> 00:11:14,395 Any questions about that? 199 00:11:14,395 --> 00:11:15,770 We can ignore that error for now. 200 00:11:15,770 --> 00:11:19,030 201 00:11:19,030 --> 00:11:23,570 Cool, so is that a real phone number, one two three four? 202 00:11:23,570 --> 00:11:24,070 It's not. 203 00:11:24,070 --> 00:11:30,700 So we should add some way to check whether the input is valid or not. 204 00:11:30,700 --> 00:11:34,480 And so next we'll talk about validating input. 205 00:11:34,480 --> 00:11:36,490 So one way to go ahead and validate input 206 00:11:36,490 --> 00:11:38,950 is to conditionally set the state based on input value. 207 00:11:38,950 --> 00:11:42,250 And so one bug that we actually have here, 208 00:11:42,250 --> 00:11:47,240 is even though for the phone number only numbers are showing up, 209 00:11:47,240 --> 00:11:49,162 one, I can type dots. 210 00:11:49,162 --> 00:11:50,245 That's probably not ideal. 211 00:11:50,245 --> 00:11:52,840 212 00:11:52,840 --> 00:11:55,210 And then, things break if I don't define a name. 213 00:11:55,210 --> 00:12:01,220 214 00:12:01,220 --> 00:12:02,750 So that is not ideal. 215 00:12:02,750 --> 00:12:09,350 And furthermore, if somebody plugs in a physical keyboard, 216 00:12:09,350 --> 00:12:15,810 they can also type things that are not numbers. 217 00:12:15,810 --> 00:12:18,650 And that is also probably not ideal. 218 00:12:18,650 --> 00:12:22,510 And so let's figure out some sort of way to say, hey, 219 00:12:22,510 --> 00:12:27,070 if this phone number is not a real phone number, we should not accept it. 220 00:12:27,070 --> 00:12:29,790 And so one way to do that is to conditionally set 221 00:12:29,790 --> 00:12:32,290 the state based on the input value. 222 00:12:32,290 --> 00:12:37,310 So let's go back into that form and do that. 223 00:12:37,310 --> 00:12:43,480 And so where might we want to check the value of that phone number 224 00:12:43,480 --> 00:12:47,740 before we update the state? 225 00:12:47,740 --> 00:12:51,280 So on line 33 here, we define the handle phone change, 226 00:12:51,280 --> 00:12:55,062 which is the function that gets invoked every single time that input changes. 227 00:12:55,062 --> 00:12:57,520 In what we're doing is we're immediately taking that string 228 00:12:57,520 --> 00:13:01,660 and setting the phone in the state to be whatever 229 00:13:01,660 --> 00:13:04,332 arbitrary string is passed to us. 230 00:13:04,332 --> 00:13:05,540 But we don't have to do that. 231 00:13:05,540 --> 00:13:08,060 We can actually add some logic here that says, hey, 232 00:13:08,060 --> 00:13:11,260 we should only allow people to set phone numbers to something 233 00:13:11,260 --> 00:13:14,494 that resembles a phone number. 234 00:13:14,494 --> 00:13:15,910 And so let's go ahead and do that. 235 00:13:15,910 --> 00:13:18,620 236 00:13:18,620 --> 00:13:26,980 So we can say if phone, and then maybe do something there, then set the state. 237 00:13:26,980 --> 00:13:28,821 Otherwise, just don't do anything. 238 00:13:28,821 --> 00:13:30,820 And so what might we want to check on the phone? 239 00:13:30,820 --> 00:13:33,370 240 00:13:33,370 --> 00:13:35,000 We should check if it's a number. 241 00:13:35,000 --> 00:13:39,205 And so how do we check if a string is a number? 242 00:13:39,205 --> 00:13:44,120 There are actually many different ways and I'll show you one possible way. 243 00:13:44,120 --> 00:13:48,470 So this plus notation, if you do plus some string, 244 00:13:48,470 --> 00:13:50,810 it will try to cast that to a number. 245 00:13:50,810 --> 00:13:53,110 And so let's, I can show you real quick. 246 00:13:53,110 --> 00:14:00,350 247 00:14:00,350 --> 00:14:06,890 So say we have a string that's one, two, three. 248 00:14:06,890 --> 00:14:11,870 If I just do +str, we get one, two, three as a number. 249 00:14:11,870 --> 00:14:14,440 But what if I do plus one, two, three, a. 250 00:14:14,440 --> 00:14:17,600 Not a number. 251 00:14:17,600 --> 00:14:20,560 Plus empty string is the case where it will return zero. 252 00:14:20,560 --> 00:14:23,120 253 00:14:23,120 --> 00:14:29,960 But anything else that's not a number, will return not a number. 254 00:14:29,960 --> 00:14:34,430 And so we can use this new operator to check 255 00:14:34,430 --> 00:14:36,320 if our phone number is indeed a number. 256 00:14:36,320 --> 00:14:41,320 257 00:14:41,320 --> 00:14:44,580 Let's go ahead and say if the phone number is indeed 258 00:14:44,580 --> 00:14:48,375 a number, so is greater than or equal to zero, 259 00:14:48,375 --> 00:14:50,000 then we can go ahead and set the state. 260 00:14:50,000 --> 00:14:58,740 261 00:14:58,740 --> 00:15:04,170 And so now here, if we start to type, I'm pressing letters 262 00:15:04,170 --> 00:15:06,910 and nothing's happening. 263 00:15:06,910 --> 00:15:10,380 That's because any single time that I type a letter, 264 00:15:10,380 --> 00:15:12,480 it's going to invoke this function. 265 00:15:12,480 --> 00:15:16,716 It's going to do if plus some letter, or not a number, 266 00:15:16,716 --> 00:15:18,090 is greater than or equal to zero. 267 00:15:18,090 --> 00:15:20,689 Not a number is never going to be greater than or equal to 0. 268 00:15:20,689 --> 00:15:22,980 And so that's never actually going to invoke down here. 269 00:15:22,980 --> 00:15:28,130 270 00:15:28,130 --> 00:15:32,740 There's still a bug where if I do one, actually there is no bug. 271 00:15:32,740 --> 00:15:38,380 272 00:15:38,380 --> 00:15:39,460 Right. 273 00:15:39,460 --> 00:15:44,836 So I was thinking that if we typed empty string here, this would be 0. 274 00:15:44,836 --> 00:15:46,210 But that still evaluates to true. 275 00:15:46,210 --> 00:15:52,480 And so even though phone is an empty string, plus empty string equals 0 276 00:15:52,480 --> 00:15:53,830 is indeed equal to 0. 277 00:15:53,830 --> 00:15:59,960 And so it will indeed set the phone number to empty string. 278 00:15:59,960 --> 00:16:02,180 So that's one way to validate the phone number. 279 00:16:02,180 --> 00:16:06,599 And so now we are ensuring that the phone is some sort of number. 280 00:16:06,599 --> 00:16:08,890 We can go a little bit further, because there's nothing 281 00:16:08,890 --> 00:16:13,977 stopping me from inputting a lot of numbers as my phone number. 282 00:16:13,977 --> 00:16:16,060 So let's just assume that all phone numbers should 283 00:16:16,060 --> 00:16:20,200 be 10 digits long, until we can stop the user from putting a number that's 284 00:16:20,200 --> 00:16:23,650 greater than 10 digits long. 285 00:16:23,650 --> 00:16:24,620 How might we do that? 286 00:16:24,620 --> 00:16:32,380 Well, we can just do if phone, dot length. 287 00:16:32,380 --> 00:16:35,280 And since it's a string, we can just check the length of it. 288 00:16:35,280 --> 00:16:39,466 As long as it's less than or equal to 10, we can go ahead and update it. 289 00:16:39,466 --> 00:16:42,730 290 00:16:42,730 --> 00:16:47,652 And so now if we do one, two, three, four, five, six, seven, eight, nine, 291 00:16:47,652 --> 00:16:54,941 ten, if I try to press additional numbers, it doesn't update. 292 00:16:54,941 --> 00:16:55,440 Why? 293 00:16:55,440 --> 00:17:01,590 Because when I try to set phone to a string of length larger than 10, 294 00:17:01,590 --> 00:17:03,300 this does not evaluate to true. 295 00:17:03,300 --> 00:17:05,020 And so the state does not get updated. 296 00:17:05,020 --> 00:17:10,781 297 00:17:10,781 --> 00:17:12,030 So there's still problem here. 298 00:17:12,030 --> 00:17:13,530 What happens if I just click submit? 299 00:17:13,530 --> 00:17:16,569 Well, it errors because there's no name. 300 00:17:16,569 --> 00:17:19,695 And so we should probably also check that the name exists. 301 00:17:19,695 --> 00:17:23,260 302 00:17:23,260 --> 00:17:25,990 And so we should also go ahead and validate the entire form 303 00:17:25,990 --> 00:17:27,572 before submitting. 304 00:17:27,572 --> 00:17:29,030 And so what else should we do here? 305 00:17:29,030 --> 00:17:35,170 Well, when we submit we should make sure that both fields exist. 306 00:17:35,170 --> 00:17:38,360 And so we can say if the phone number is valid, 307 00:17:38,360 --> 00:17:40,990 and so let's just copy and paste this. 308 00:17:40,990 --> 00:17:47,480 309 00:17:47,480 --> 00:17:51,185 So now phone dot length should be equal to 10. 310 00:17:51,185 --> 00:17:52,185 And it should be number. 311 00:17:52,185 --> 00:17:57,490 312 00:17:57,490 --> 00:18:00,440 Additionally, we want that name to exist. 313 00:18:00,440 --> 00:18:06,300 And so let's just arbitrarily call this dot state dot name. 314 00:18:06,300 --> 00:18:10,860 Should have a length greater than or equal to 3. 315 00:18:10,860 --> 00:18:22,670 316 00:18:22,670 --> 00:18:26,620 And so now are saying if this dot state dot phone is greater than 0, 317 00:18:26,620 --> 00:18:30,910 when you cast two number, if the length is exactly equal to 10, 318 00:18:30,910 --> 00:18:35,234 and you have a name of length at least 10, then go ahead and submit the form. 319 00:18:35,234 --> 00:18:36,400 Otherwise don't do anything. 320 00:18:36,400 --> 00:18:38,950 321 00:18:38,950 --> 00:18:44,080 And so now when we try to add a contact with invalid fields, nothing happens. 322 00:18:44,080 --> 00:18:49,550 323 00:18:49,550 --> 00:18:53,060 But that's not great UI, right? 324 00:18:53,060 --> 00:18:57,670 I should be able to know that I shouldn't be able to submit this form. 325 00:18:57,670 --> 00:19:00,800 And so let's go a step further, and actually every single time we 326 00:19:00,800 --> 00:19:03,620 change the name or the phone number here, 327 00:19:03,620 --> 00:19:06,140 we can change this button to appear like it 328 00:19:06,140 --> 00:19:08,309 should be clickable or not clickable. 329 00:19:08,309 --> 00:19:10,100 And so there's an additional thing that you 330 00:19:10,100 --> 00:19:13,490 can do with button, an additional prop that you can pass. 331 00:19:13,490 --> 00:19:15,125 We can pass a prop called disabled. 332 00:19:15,125 --> 00:19:18,920 333 00:19:18,920 --> 00:19:29,180 And if we pass disabled true, then the button just looks unclickable. 334 00:19:29,180 --> 00:19:32,700 And it is unclickable. 335 00:19:32,700 --> 00:19:40,930 And so how might we use this to make the user experience of our form better? 336 00:19:40,930 --> 00:19:43,890 Well, we can actually continuously check, hey, if the form's valid, 337 00:19:43,890 --> 00:19:45,530 show the clickable button. 338 00:19:45,530 --> 00:19:52,160 And if the form is invalid, then say, hey, you can't click this button. 339 00:19:52,160 --> 00:19:56,199 And so where might we want to do that logic? 340 00:19:56,199 --> 00:19:59,240 Well, we can actually validate the form after we change any inputs value. 341 00:19:59,240 --> 00:20:02,840 342 00:20:02,840 --> 00:20:04,820 There's a couple of places we can do that. 343 00:20:04,820 --> 00:20:06,390 One in this dot set state. 344 00:20:06,390 --> 00:20:08,480 And so we've been using this dot set state, 345 00:20:08,480 --> 00:20:10,313 and we've been passing it one of two things. 346 00:20:10,313 --> 00:20:14,300 We pass it an object, if we want to just merge that object to the current state. 347 00:20:14,300 --> 00:20:17,000 Or we've passed it some sort of update or function, which 348 00:20:17,000 --> 00:20:21,470 is a function that takes the previous state and modifies or returns an object 349 00:20:21,470 --> 00:20:23,450 modifying that previous state. 350 00:20:23,450 --> 00:20:26,510 Well it turns out, you can actually also pass a second argument 351 00:20:26,510 --> 00:20:27,930 to this dot set state. 352 00:20:27,930 --> 00:20:30,560 And that second argument gets invoked as a callback. 353 00:20:30,560 --> 00:20:35,780 So after the state is done updating, it then invokes this callback. 354 00:20:35,780 --> 00:20:39,980 And so let's go ahead and use that to validate our form. 355 00:20:39,980 --> 00:20:43,739 So one, rather than just hard coding disabled true here, 356 00:20:43,739 --> 00:20:44,780 what might we want to do? 357 00:20:44,780 --> 00:20:48,590 358 00:20:48,590 --> 00:20:53,020 Well, we can store in our state whether or not this form is valid. 359 00:20:53,020 --> 00:20:59,590 So let's just call this is valid form, or is form valid. 360 00:20:59,590 --> 00:21:03,640 And we know that when the form is first created, that it's not. 361 00:21:03,640 --> 00:21:07,440 And so we can just initialize this value to be false. 362 00:21:07,440 --> 00:21:10,380 And so down here in the button, we can say whether or not 363 00:21:10,380 --> 00:21:15,720 it's disabled depends on the value of this dot state dot is form valid. 364 00:21:15,720 --> 00:21:18,450 365 00:21:18,450 --> 00:21:23,640 So this will always start as an invalid form and so we can see, oops. 366 00:21:23,640 --> 00:21:26,990 367 00:21:26,990 --> 00:21:30,260 It should be disabled when the form is not valid. 368 00:21:30,260 --> 00:21:33,310 369 00:21:33,310 --> 00:21:38,055 And so we can see that when the form is first created, since is form valid 370 00:21:38,055 --> 00:21:41,000 is false, we can't submit the form. 371 00:21:41,000 --> 00:21:43,130 That button is disabled. 372 00:21:43,130 --> 00:21:45,020 And now we can add some logic to say, hey, 373 00:21:45,020 --> 00:21:48,312 every single time we check the input, the form may now be valid. 374 00:21:48,312 --> 00:21:49,520 How might we want to do that? 375 00:21:49,520 --> 00:21:52,875 376 00:21:52,875 --> 00:21:55,500 We're currently checking whether or not the form is valid right 377 00:21:55,500 --> 00:21:58,210 before we submit the form. 378 00:21:58,210 --> 00:22:01,560 But there's nothing stopping us from just abstracting that out 379 00:22:01,560 --> 00:22:02,880 to a new function. 380 00:22:02,880 --> 00:22:04,860 So let's call this validate form. 381 00:22:04,860 --> 00:22:07,590 382 00:22:07,590 --> 00:22:09,180 And it doesn't need any arguments. 383 00:22:09,180 --> 00:22:12,221 Just because we're going to call it, and it will check the current state. 384 00:22:12,221 --> 00:22:15,130 385 00:22:15,130 --> 00:22:21,730 And so here we can say, well, if these things are true, 386 00:22:21,730 --> 00:22:23,070 then maybe return true. 387 00:22:23,070 --> 00:22:27,350 388 00:22:27,350 --> 00:22:28,790 Else return false. 389 00:22:28,790 --> 00:22:31,290 Because it's not a valid form. 390 00:22:31,290 --> 00:22:41,400 391 00:22:41,400 --> 00:22:44,790 And so although this isn't perfect, we can still 392 00:22:44,790 --> 00:22:48,810 have dots in our phone number. 393 00:22:48,810 --> 00:22:49,560 It's close enough. 394 00:22:49,560 --> 00:22:52,440 And so now, when we invoke validate form, it's going to check. 395 00:22:52,440 --> 00:22:57,630 Hey, is the phone as a number greater than zero? 396 00:22:57,630 --> 00:22:59,580 And is it of length 10? 397 00:22:59,580 --> 00:23:05,280 So we'll just call that a phone number, even though it's not 100% rigid. 398 00:23:05,280 --> 00:23:07,636 And then, did they put something as their name? 399 00:23:07,636 --> 00:23:09,260 It has to be at least three characters. 400 00:23:09,260 --> 00:23:12,390 And if that's true, then it will say, hey, it's a valid form. 401 00:23:12,390 --> 00:23:16,310 Otherwise, no it's not a valid form. 402 00:23:16,310 --> 00:23:21,480 And so where should we invoke this function? 403 00:23:21,480 --> 00:23:24,210 Well, after a value changes. 404 00:23:24,210 --> 00:23:27,210 And so right now the only two places that the values are updated, 405 00:23:27,210 --> 00:23:32,050 are in this handle name change function and this handle phone change function. 406 00:23:32,050 --> 00:23:35,840 And so we can pass now as a second argument to this dot set state, 407 00:23:35,840 --> 00:23:37,120 this dot validate form. 408 00:23:37,120 --> 00:23:39,910 409 00:23:39,910 --> 00:23:44,544 And as a second argument to handle phone change, the set state here, 410 00:23:44,544 --> 00:23:46,210 we can also pass this dot validate form. 411 00:23:46,210 --> 00:23:49,680 412 00:23:49,680 --> 00:23:51,750 And now this validate form function is going 413 00:23:51,750 --> 00:23:54,930 to get called after either of those functions are fired. 414 00:23:54,930 --> 00:23:57,826 415 00:23:57,826 --> 00:24:00,950 As we've currently written it, validate form does not actually do anything. 416 00:24:00,950 --> 00:24:02,530 It just returns true or false. 417 00:24:02,530 --> 00:24:05,020 And so what should we do instead? 418 00:24:05,020 --> 00:24:08,310 Well, this should tell us whether the form is valid. 419 00:24:08,310 --> 00:24:11,250 And so if the form is valid, let's actually set state here too. 420 00:24:11,250 --> 00:24:33,350 421 00:24:33,350 --> 00:24:36,410 Now in validate form, rather than just returning true or false, 422 00:24:36,410 --> 00:24:40,420 it will actually update the state such that the is form valid field 423 00:24:40,420 --> 00:24:43,500 gets updated to true or false. 424 00:24:43,500 --> 00:24:46,730 So now let's see how our application functions. 425 00:24:46,730 --> 00:24:51,820 So when we first start this form, the submit button does not work. 426 00:24:51,820 --> 00:24:55,210 And let's add a name of two letters. 427 00:24:55,210 --> 00:24:58,269 And a phone number of 10. 428 00:24:58,269 --> 00:24:59,560 And the validation still works. 429 00:24:59,560 --> 00:25:04,760 If we try to type more here, it doesn't let us. 430 00:25:04,760 --> 00:25:06,410 And now, let's type a third letter. 431 00:25:06,410 --> 00:25:09,560 And all of a sudden that submit button works. 432 00:25:09,560 --> 00:25:11,530 Why? 433 00:25:11,530 --> 00:25:17,240 Well, because when we pass another argument to set state here, 434 00:25:17,240 --> 00:25:20,180 that gets invoked after the state is set. 435 00:25:20,180 --> 00:25:24,050 And so after it updates the name value, now the name value in state 436 00:25:24,050 --> 00:25:26,510 is whatever it was when we typed in the input. 437 00:25:26,510 --> 00:25:28,010 And then it fires off this function. 438 00:25:28,010 --> 00:25:31,610 And this function says, hey, if the phone number is valid 439 00:25:31,610 --> 00:25:34,790 and the name is at least three characters, go ahead 440 00:25:34,790 --> 00:25:37,220 and say the form is valid. 441 00:25:37,220 --> 00:25:41,300 And what it's listening to that is form valid part of the state, 442 00:25:41,300 --> 00:25:42,630 well it's the button down here. 443 00:25:42,630 --> 00:25:44,930 And so when that is updated, the button then 444 00:25:44,930 --> 00:25:49,100 flips from disabled to not disabled. 445 00:25:49,100 --> 00:25:52,310 And when we delete this and when it becomes invalid again, 446 00:25:52,310 --> 00:25:58,530 that submit button reflects the in-validness of the form. 447 00:25:58,530 --> 00:26:03,090 448 00:26:03,090 --> 00:26:04,440 Any questions so far? 449 00:26:04,440 --> 00:26:07,000 450 00:26:07,000 --> 00:26:09,870 So how are other ways that we can do this? 451 00:26:09,870 --> 00:26:12,720 Well, we learned a few weeks ago about the component lifecycle. 452 00:26:12,720 --> 00:26:16,360 And how there are certain functions that are called every single time 453 00:26:16,360 --> 00:26:19,510 a React component does something. 454 00:26:19,510 --> 00:26:22,530 And in this case, we can actually use that, 455 00:26:22,530 --> 00:26:26,640 the hook that's invoked every single time the form or the component updates 456 00:26:26,640 --> 00:26:29,260 to go ahead and fire this as well. 457 00:26:29,260 --> 00:26:34,800 And so if we wanted to, rather than invoking this dot validate form 458 00:26:34,800 --> 00:26:41,530 and handle phone change and handle name change, 459 00:26:41,530 --> 00:26:47,840 we could also do that in the component did update. 460 00:26:47,840 --> 00:26:51,130 461 00:26:51,130 --> 00:26:55,220 And component did update takes a couple of different arguments. 462 00:26:55,220 --> 00:26:58,840 One is prevProps and one is prevState. 463 00:26:58,840 --> 00:27:01,571 464 00:27:01,571 --> 00:27:02,570 And what can we do here? 465 00:27:02,570 --> 00:27:05,560 Well, we can just call this dot validate form. 466 00:27:05,560 --> 00:27:10,900 467 00:27:10,900 --> 00:27:14,510 And so something interesting is going to happen here. 468 00:27:14,510 --> 00:27:20,672 469 00:27:20,672 --> 00:27:22,580 Hm. 470 00:27:22,580 --> 00:27:25,050 We got a big error screen. 471 00:27:25,050 --> 00:27:26,386 Maximum update depth exceeded. 472 00:27:26,386 --> 00:27:28,260 This can happen when the component repeatedly 473 00:27:28,260 --> 00:27:35,910 calls set state inside one of these component lifecycle hooks. 474 00:27:35,910 --> 00:27:38,820 And so React is saying, hey, rather than just infinitely looping, 475 00:27:38,820 --> 00:27:40,720 we just threw an error. 476 00:27:40,720 --> 00:27:42,460 And so what is happening here? 477 00:27:42,460 --> 00:27:45,430 478 00:27:45,430 --> 00:27:47,410 Let's take a look. 479 00:27:47,410 --> 00:27:51,370 480 00:27:51,370 --> 00:27:54,120 So when we go ahead and type into type and input here, 481 00:27:54,120 --> 00:27:57,060 text input, something happens. 482 00:27:57,060 --> 00:28:01,759 One of these two functions is going to be invoked. 483 00:28:01,759 --> 00:28:03,050 What happens when it's invoked? 484 00:28:03,050 --> 00:28:04,815 Well, the whole component updates. 485 00:28:04,815 --> 00:28:07,830 486 00:28:07,830 --> 00:28:11,240 And when the component updates, it calls this dot validate form. 487 00:28:11,240 --> 00:28:12,960 What does this dot validate form do? 488 00:28:12,960 --> 00:28:18,154 Well, it checks some things and then calls set state. 489 00:28:18,154 --> 00:28:20,445 And then when set state happens, the component updates. 490 00:28:20,445 --> 00:28:22,410 And what happens when the component updates? 491 00:28:22,410 --> 00:28:24,406 Well, it validates the form. 492 00:28:24,406 --> 00:28:26,280 And then what happens when you validate form? 493 00:28:26,280 --> 00:28:27,840 Well, the component updates. 494 00:28:27,840 --> 00:28:33,120 And so we entered a cycle where it just infinite loops. 495 00:28:33,120 --> 00:28:34,500 So how can we fix that? 496 00:28:34,500 --> 00:28:37,070 497 00:28:37,070 --> 00:28:39,850 Well component did update knows about the previous props 498 00:28:39,850 --> 00:28:41,070 and the previous states. 499 00:28:41,070 --> 00:28:43,570 It also knows about the current props and the current state. 500 00:28:43,570 --> 00:28:45,880 And so we can go ahead and check those values. 501 00:28:45,880 --> 00:28:52,120 And say, if this dot state dot name is different than what 502 00:28:52,120 --> 00:28:55,893 the previous state dot name was, or this dot 503 00:28:55,893 --> 00:29:06,760 state dot phone is different than it used to be, then validate the form. 504 00:29:06,760 --> 00:29:08,170 Otherwise don't do anything. 505 00:29:08,170 --> 00:29:12,410 506 00:29:12,410 --> 00:29:17,010 And so now when we do stuff like this, it works. 507 00:29:17,010 --> 00:29:22,889 And when we type a tentative phone number, then the form becomes valid. 508 00:29:22,889 --> 00:29:24,180 What happens when it's invalid? 509 00:29:24,180 --> 00:29:25,915 Well, it works as expected. 510 00:29:25,915 --> 00:29:28,960 And then when it becomes valid again, then all of a sudden 511 00:29:28,960 --> 00:29:31,239 that submit button appears again. 512 00:29:31,239 --> 00:29:33,030 And then everything else works as expected. 513 00:29:33,030 --> 00:29:37,720 514 00:29:37,720 --> 00:29:39,620 And so the other place that we can validate 515 00:29:39,620 --> 00:29:43,160 a form is just in that component did update lifecycle hook. 516 00:29:43,160 --> 00:29:44,870 And so what's the difference? 517 00:29:44,870 --> 00:29:46,830 Well, not much. 518 00:29:46,830 --> 00:29:51,540 One difference is that when we add new functions, 519 00:29:51,540 --> 00:29:53,900 we also need to remember that in the set state, 520 00:29:53,900 --> 00:29:57,260 we need to pass that validate form field. 521 00:29:57,260 --> 00:30:00,210 But on the flip side, every time we add a new input, 522 00:30:00,210 --> 00:30:02,390 we also need to make sure that we're listening 523 00:30:02,390 --> 00:30:05,750 at the correct times in component did update. 524 00:30:05,750 --> 00:30:08,490 And so the performance of the two is equal. 525 00:30:08,490 --> 00:30:13,456 And so, whether you choose one or the other is more personal preference. 526 00:30:13,456 --> 00:30:16,330 The way I would write it is I would prefer to put it in the component 527 00:30:16,330 --> 00:30:21,000 did update, but it's really up to you. 528 00:30:21,000 --> 00:30:23,425 This is almost complete personal preference. 529 00:30:23,425 --> 00:30:27,070 530 00:30:27,070 --> 00:30:32,821 Any questions this far? 531 00:30:32,821 --> 00:30:33,819 Yeah? 532 00:30:33,819 --> 00:30:38,310 SPEAKER 2: So when you put the is for valid function 533 00:30:38,310 --> 00:30:44,298 directly in the disable attribute, does it know 534 00:30:44,298 --> 00:30:48,290 to-- does it not know to update that? 535 00:30:48,290 --> 00:30:53,610 SPEAKER 1: So the question was, when you put the is form valid value here, 536 00:30:53,610 --> 00:30:56,730 does it know to update that? 537 00:30:56,730 --> 00:30:57,230 And so, yes. 538 00:30:57,230 --> 00:31:00,530 So this is not the is form valid function. 539 00:31:00,530 --> 00:31:03,710 It's just the state key called is form valid. 540 00:31:03,710 --> 00:31:11,300 And the is form valid key is updated when the validate form is called. 541 00:31:11,300 --> 00:31:15,200 And so React knows every single time the state is updated 542 00:31:15,200 --> 00:31:17,432 that the render might change. 543 00:31:17,432 --> 00:31:19,140 So it's outputted by render might change. 544 00:31:19,140 --> 00:31:21,800 And so every single time we call this dot set state, 545 00:31:21,800 --> 00:31:23,660 the component is then re-rendered. 546 00:31:23,660 --> 00:31:29,320 And the correct value of is form valid will be placed as this disabled prop 547 00:31:29,320 --> 00:31:31,560 to the button. 548 00:31:31,560 --> 00:31:34,706 SPEAKER 2: Do you always have to use the state 549 00:31:34,706 --> 00:31:38,336 to determine whether disable is true or not? 550 00:31:38,336 --> 00:31:43,107 Can you use a function instead? 551 00:31:43,107 --> 00:31:44,940 SPEAKER 1: So the question was, do we always 552 00:31:44,940 --> 00:31:49,290 have to use the state field to determine whether or not 553 00:31:49,290 --> 00:31:52,500 this form is disabled or not? 554 00:31:52,500 --> 00:31:55,950 Could we just use an inline function instead? 555 00:31:55,950 --> 00:31:57,720 So the answer is no. 556 00:31:57,720 --> 00:32:03,150 So we could definitely-- we can use a function here instead. 557 00:32:03,150 --> 00:32:09,015 And so say we actually validate form. 558 00:32:09,015 --> 00:32:11,730 559 00:32:11,730 --> 00:32:16,329 Say we implemented it how we did at first. 560 00:32:16,329 --> 00:32:18,120 So let's call this validate form two, where 561 00:32:18,120 --> 00:32:24,090 rather than setting state to update that is form valid field, 562 00:32:24,090 --> 00:32:27,390 we just return true or return false. 563 00:32:27,390 --> 00:32:31,440 564 00:32:31,440 --> 00:32:34,491 And then we can-- 565 00:32:34,491 --> 00:32:36,740 and so now down here we can just invoke that function. 566 00:32:36,740 --> 00:32:43,680 567 00:32:43,680 --> 00:32:45,530 This should work. 568 00:32:45,530 --> 00:32:58,500 So now if we oops- This dot is form valid two. 569 00:32:58,500 --> 00:33:00,880 Validate form two. 570 00:33:00,880 --> 00:33:11,530 So if we call this validate form two, so this should, in theory, work. 571 00:33:11,530 --> 00:33:16,180 572 00:33:16,180 --> 00:33:22,480 I forgot to flip the Boolean, but you see that the Boolean does change. 573 00:33:22,480 --> 00:33:25,040 And so what is that what is the difference between these two? 574 00:33:25,040 --> 00:33:30,730 The difference here is that this function is actually being 575 00:33:30,730 --> 00:33:33,490 computed as the render is happening. 576 00:33:33,490 --> 00:33:37,480 And so say it took a lot of work in order to validate this form. 577 00:33:37,480 --> 00:33:40,540 Say it took a whole second. 578 00:33:40,540 --> 00:33:43,360 What's happening to the user in that second? 579 00:33:43,360 --> 00:33:46,400 Well nothing's showing up because React doesn't yet know what to render. 580 00:33:46,400 --> 00:33:49,720 And so the render here will take a full second. 581 00:33:49,720 --> 00:33:54,670 And so the user won't see anything until a second later. 582 00:33:54,670 --> 00:33:58,360 And so that's considered bad user experience. 583 00:33:58,360 --> 00:34:04,166 Whereas, when we do the validate form in the update cycle, 584 00:34:04,166 --> 00:34:05,290 it's already rendered this. 585 00:34:05,290 --> 00:34:07,660 So the user's already seeing this. 586 00:34:07,660 --> 00:34:11,500 And then when the component's updating, that's when it does the computing. 587 00:34:11,500 --> 00:34:14,530 And so the user sees what the user needs to see. 588 00:34:14,530 --> 00:34:18,070 And then the expensive computation is done after the user has already 589 00:34:18,070 --> 00:34:19,179 seen the form. 590 00:34:19,179 --> 00:34:21,520 And so there is, on the user side, he gets 591 00:34:21,520 --> 00:34:25,991 to see the form rendered before this is calculated. 592 00:34:25,991 --> 00:34:29,199 And so if you do it inline here, it's actually going to slow down the render. 593 00:34:29,199 --> 00:34:31,479 Whereas if you do it in like component did update, 594 00:34:31,479 --> 00:34:33,020 it actually happens after the render. 595 00:34:33,020 --> 00:34:38,500 And so the user gets to see the form before this computation happening. 596 00:34:38,500 --> 00:34:41,719 And so it would be better to just store that value in state. 597 00:34:41,719 --> 00:34:44,290 That way you can recompute it at a convenient time, 598 00:34:44,290 --> 00:34:47,650 rather than having to do a potentially expensive computation 599 00:34:47,650 --> 00:34:49,715 during the render. 600 00:34:49,715 --> 00:34:50,590 Does that make sense? 601 00:34:50,590 --> 00:34:55,749 602 00:34:55,749 --> 00:34:56,690 Cool. 603 00:34:56,690 --> 00:35:03,887 So let's revert this to this dot state dot is valid form. 604 00:35:03,887 --> 00:35:05,220 And we're back to where we were. 605 00:35:05,220 --> 00:35:12,470 606 00:35:12,470 --> 00:35:15,315 Great, so this works really well for short forms. 607 00:35:15,315 --> 00:35:23,110 But what happens if, say we wanted to center the form. 608 00:35:23,110 --> 00:35:32,190 609 00:35:32,190 --> 00:35:37,260 So now, in my opinion, the form looks slightly better. 610 00:35:37,260 --> 00:35:39,450 But when we're bringing up the keyboard, it's 611 00:35:39,450 --> 00:35:44,070 starting to get dangerously close to the input here. 612 00:35:44,070 --> 00:35:46,320 And so what happens if this form were slightly longer? 613 00:35:46,320 --> 00:35:54,060 614 00:35:54,060 --> 00:35:57,480 Say now we had six things to fill out. 615 00:35:57,480 --> 00:36:02,850 Now when we click phone, uh oh we have something that's considered probably 616 00:36:02,850 --> 00:36:05,610 some bad user experience. 617 00:36:05,610 --> 00:36:09,360 That is, the input's getting covered up by the keyboard itself. 618 00:36:09,360 --> 00:36:11,850 And so you may start to run into problems like these 619 00:36:11,850 --> 00:36:13,850 when you're working on your projects. 620 00:36:13,850 --> 00:36:15,720 And so how might we go about in fixing that? 621 00:36:15,720 --> 00:36:19,270 622 00:36:19,270 --> 00:36:21,440 So it turns out, there's this thing called 623 00:36:21,440 --> 00:36:24,330 a keyboard avoiding view, which is a native component 624 00:36:24,330 --> 00:36:28,020 to handle avoiding that virtual keyboard. 625 00:36:28,020 --> 00:36:30,600 It's good for simple or short forms, but it doesn't really 626 00:36:30,600 --> 00:36:34,600 work well for very complex things. 627 00:36:34,600 --> 00:36:37,530 And what happens here, and the reason that's not good, 628 00:36:37,530 --> 00:36:41,750 is because the view moves independent of any of its child text inputs. 629 00:36:41,750 --> 00:36:46,730 Let's take a look at usage of this component. 630 00:36:46,730 --> 00:36:51,510 So right now we have a view that surrounds these inputs. 631 00:36:51,510 --> 00:36:57,031 And let's actually import this thing called a keyboard avoiding view 632 00:36:57,031 --> 00:36:57,530 instead. 633 00:36:57,530 --> 00:37:00,190 634 00:37:00,190 --> 00:37:07,820 So now, rather than just using a view, we can use that keyboard avoiding view. 635 00:37:07,820 --> 00:37:09,670 And same up here. 636 00:37:09,670 --> 00:37:14,350 637 00:37:14,350 --> 00:37:18,970 So now the keyboard avoiding view that actually doesn't look like it's 638 00:37:18,970 --> 00:37:21,010 doing much. 639 00:37:21,010 --> 00:37:24,720 That's because we need to tell it what to do when the keyboard arrives. 640 00:37:24,720 --> 00:37:27,235 And so we can pass this prop called behavior. 641 00:37:27,235 --> 00:37:31,390 642 00:37:31,390 --> 00:37:36,681 Which is saying, hey, what should I adjust when that keyboard appears? 643 00:37:36,681 --> 00:37:37,930 It can be one of three things. 644 00:37:37,930 --> 00:37:41,500 It can be padding, which means when the keyboard appears, 645 00:37:41,500 --> 00:37:44,240 go ahead and add some padding to the bottom of the view 646 00:37:44,240 --> 00:37:46,730 so all of the content moves up. 647 00:37:46,730 --> 00:37:51,130 It can be height, so that rather than being a full height view, 648 00:37:51,130 --> 00:37:53,800 it will actually change the height of that view. 649 00:37:53,800 --> 00:37:56,860 Or third, it could be position where it actually repositions the view. 650 00:37:56,860 --> 00:38:00,220 651 00:38:00,220 --> 00:38:02,570 Which one is best depends a lot on your use case. 652 00:38:02,570 --> 00:38:06,430 And so, the docs say, hey, just try whichever one is best in it. 653 00:38:06,430 --> 00:38:07,237 You'll see. 654 00:38:07,237 --> 00:38:09,070 And so here, let's go ahead and use padding. 655 00:38:09,070 --> 00:38:11,810 656 00:38:11,810 --> 00:38:16,480 And so now we specified some behavior for that keyboard avoiding view. 657 00:38:16,480 --> 00:38:21,640 And so when we click, it goes ahead and moves that view out 658 00:38:21,640 --> 00:38:23,482 of the way of the keyboard. 659 00:38:23,482 --> 00:38:25,690 And when we're done, it goes ahead and moves it back. 660 00:38:25,690 --> 00:38:27,140 And how does this happen? 661 00:38:27,140 --> 00:38:31,540 Well, this view just gets some added padding. 662 00:38:31,540 --> 00:38:37,010 663 00:38:37,010 --> 00:38:41,600 So this is a relatively new component and it is still getting better. 664 00:38:41,600 --> 00:38:48,570 And so hopefully, this will be able to handle larger forms in the future. 665 00:38:48,570 --> 00:38:54,110 But for now, it works perfectly well for small forms that 666 00:38:54,110 --> 00:38:57,230 will fit in the space outside the view. 667 00:38:57,230 --> 00:39:01,502 So any questions on user input at all? 668 00:39:01,502 --> 00:39:02,187 Cool. 669 00:39:02,187 --> 00:39:03,770 Let's go ahead and take a short break. 670 00:39:03,770 --> 00:39:08,000 And then after the break, we'll go ahead and look get some debugging techniques. 671 00:39:08,000 --> 00:39:09,150 Hello and welcome back. 672 00:39:09,150 --> 00:39:12,680 So before the break, we were talking about a few different forms 673 00:39:12,680 --> 00:39:15,050 and how we handle user input in the forms. 674 00:39:15,050 --> 00:39:17,890 And there was a question in Slack asking a great question. 675 00:39:17,890 --> 00:39:21,170 And so in this form right here, we have two different inputs. 676 00:39:21,170 --> 00:39:23,180 We have the name in the phone. 677 00:39:23,180 --> 00:39:24,920 And we also have two different handlers. 678 00:39:24,920 --> 00:39:27,830 We have the handle name change and handle phone change. 679 00:39:27,830 --> 00:39:29,630 This doesn't scale super well. 680 00:39:29,630 --> 00:39:32,780 Imagine you have a form with 100 different inputs. 681 00:39:32,780 --> 00:39:35,540 It would not really be a great component if it 682 00:39:35,540 --> 00:39:38,560 were filled with a hundreds different handlers for all those inputs. 683 00:39:38,560 --> 00:39:43,040 And so let's go ahead and take a look at a pattern for how we can go ahead 684 00:39:43,040 --> 00:39:46,360 and update all of those handlers, but not 685 00:39:46,360 --> 00:39:49,070 have to write separate handlers for each of the separate fields. 686 00:39:49,070 --> 00:39:51,680 687 00:39:51,680 --> 00:39:57,570 So if you notice, both of these handles look very similar. 688 00:39:57,570 --> 00:40:02,000 We have some string that gets passed in, and then we set the state such 689 00:40:02,000 --> 00:40:04,260 that the key is equal to that string. 690 00:40:04,260 --> 00:40:06,099 And the phone does some validation before, 691 00:40:06,099 --> 00:40:07,640 but it basically does the same thing. 692 00:40:07,640 --> 00:40:11,020 It takes a string and sets a particular key equal to that string. 693 00:40:11,020 --> 00:40:12,950 And so we can go ahead and abstract that out 694 00:40:12,950 --> 00:40:16,770 into a more generic updating function. 695 00:40:16,770 --> 00:40:20,450 So let's just call it handle update. 696 00:40:20,450 --> 00:40:23,180 697 00:40:23,180 --> 00:40:26,480 And that's going to take a couple different arguments. 698 00:40:26,480 --> 00:40:34,760 Let's actually have it take a key and return a function. 699 00:40:34,760 --> 00:40:39,996 It's going to return a function that says, take some sort of value, 700 00:40:39,996 --> 00:40:41,370 and then call this dot set state. 701 00:40:41,370 --> 00:40:51,110 702 00:40:51,110 --> 00:40:53,330 And then the object here, we're going to do something 703 00:40:53,330 --> 00:40:55,550 with the key and something with the value. 704 00:40:55,550 --> 00:40:57,890 And so we're going to take that original key 705 00:40:57,890 --> 00:41:04,760 and call it here and update the state to be that value. 706 00:41:04,760 --> 00:41:07,560 707 00:41:07,560 --> 00:41:10,790 And so for those of you haven't seen this notation before, 708 00:41:10,790 --> 00:41:13,860 this basically means evaluate this expression. 709 00:41:13,860 --> 00:41:16,080 And whatever it evaluates to, cast it to a string 710 00:41:16,080 --> 00:41:18,860 and that's going to be the key of that object. 711 00:41:18,860 --> 00:41:23,560 And so in this handle update function, we pass it a key first. 712 00:41:23,560 --> 00:41:33,650 And so imagine we want to do the handle name change rather than doing this, 713 00:41:33,650 --> 00:41:39,290 we can actually do handle name change is equal to this dot handle update. 714 00:41:39,290 --> 00:41:42,790 715 00:41:42,790 --> 00:41:44,900 And we're passing it a key called name. 716 00:41:44,900 --> 00:41:48,716 717 00:41:48,716 --> 00:41:50,470 Well what does that return? 718 00:41:50,470 --> 00:41:52,370 We can go ahead and evaluate in our head. 719 00:41:52,370 --> 00:41:55,250 So handle update is going to be invoked with name. 720 00:41:55,250 --> 00:42:01,440 And so you're basically passing in name here, as the key, 721 00:42:01,440 --> 00:42:03,530 and replacing it down here. 722 00:42:03,530 --> 00:42:07,930 And so this will actually return a function that is a value. 723 00:42:07,930 --> 00:42:10,994 724 00:42:10,994 --> 00:42:12,160 And what does that value do? 725 00:42:12,160 --> 00:42:13,690 Well it calls this dot set state. 726 00:42:13,690 --> 00:42:16,272 727 00:42:16,272 --> 00:42:17,355 What does key evaluate to? 728 00:42:17,355 --> 00:42:18,380 Well it's just name. 729 00:42:18,380 --> 00:42:22,070 And it sets it equal to that bell. 730 00:42:22,070 --> 00:42:29,580 And as you noticed, this, is logically the same as this. 731 00:42:29,580 --> 00:42:32,950 So here all we're doing is having a generic updating function that 732 00:42:32,950 --> 00:42:34,490 takes some sort of key. 733 00:42:34,490 --> 00:42:38,650 And when we invoke it, it returns a handler that takes a value 734 00:42:38,650 --> 00:42:44,260 and sets the key, whatever we pass it, to be that value. 735 00:42:44,260 --> 00:42:48,910 And so certainly here we could start to do now 736 00:42:48,910 --> 00:42:54,830 handle phone change is this dot handle update. 737 00:42:54,830 --> 00:42:56,990 Let's actually name handle update to get handler. 738 00:42:56,990 --> 00:43:01,422 739 00:43:01,422 --> 00:43:02,630 So slightly more informative. 740 00:43:02,630 --> 00:43:04,300 We're getting some sort of handler. 741 00:43:04,300 --> 00:43:10,209 742 00:43:10,209 --> 00:43:10,709 Phone. 743 00:43:10,709 --> 00:43:14,660 744 00:43:14,660 --> 00:43:18,810 And so this is slightly better but, again, for 100 different inputs, 745 00:43:18,810 --> 00:43:21,060 we're still going to have 100 different handlers here. 746 00:43:21,060 --> 00:43:23,670 747 00:43:23,670 --> 00:43:26,860 And so why do we have to do it here? 748 00:43:26,860 --> 00:43:28,440 We don't, really. 749 00:43:28,440 --> 00:43:36,660 We can actually, down here, we can say for this text input called name, 750 00:43:36,660 --> 00:43:38,970 rather than doing this dot handle name change, 751 00:43:38,970 --> 00:43:44,340 we can actually just do this dot get handler down here and pass it the key 752 00:43:44,340 --> 00:43:46,770 that we want to update. 753 00:43:46,770 --> 00:43:50,280 And that's going to return a handler that takes a value 754 00:43:50,280 --> 00:43:54,670 and updates this key to be that value. 755 00:43:54,670 --> 00:44:01,210 And so for phone here, we can also do get handler and just pass it a phone. 756 00:44:01,210 --> 00:44:04,410 757 00:44:04,410 --> 00:44:08,470 And that will go ahead and create a handler for the phone. 758 00:44:08,470 --> 00:44:16,590 And so rather than having a bunch of different methods or properties, 759 00:44:16,590 --> 00:44:20,890 that handle, each of the different keys for the inputs, 760 00:44:20,890 --> 00:44:27,360 we can actually just define one generic one up here and then 761 00:44:27,360 --> 00:44:30,620 go ahead and do it. 762 00:44:30,620 --> 00:44:32,940 Actually, there's a small bug actually where 763 00:44:32,940 --> 00:44:37,860 they should be returning that function. 764 00:44:37,860 --> 00:44:48,580 But rather than doing that, we can just use the shorthand notation like this. 765 00:44:48,580 --> 00:44:54,360 So rather than having a single line return, we can just use the shorthand. 766 00:44:54,360 --> 00:44:59,774 Because arrow notation, it just implicitly returns 767 00:44:59,774 --> 00:45:00,940 whatever is after the arrow. 768 00:45:00,940 --> 00:45:03,230 So this is saying, this takes a key, and it 769 00:45:03,230 --> 00:45:09,739 returns a function that takes a value and calls dot set state. 770 00:45:09,739 --> 00:45:12,030 And so if you ever see something that looks very weird, 771 00:45:12,030 --> 00:45:13,500 like a bunch of arrows pointing. 772 00:45:13,500 --> 00:45:16,800 It just means this, when invoked, returns a function. 773 00:45:16,800 --> 00:45:18,400 Which may, in turn, return a function. 774 00:45:18,400 --> 00:45:22,050 However many arrows are just the functions that are returned. 775 00:45:22,050 --> 00:45:25,285 But here this is just saying, hey, to get a handler pass me a key, 776 00:45:25,285 --> 00:45:26,710 and I'll return you a handler. 777 00:45:26,710 --> 00:45:30,104 A function that takes a value and invokes this dot set state. 778 00:45:30,104 --> 00:45:36,440 779 00:45:36,440 --> 00:45:39,860 So hopefully that answers the question in Slack. 780 00:45:39,860 --> 00:45:41,120 And so what's the difference? 781 00:45:41,120 --> 00:45:41,810 Which is better? 782 00:45:41,810 --> 00:45:44,700 Well it depends. 783 00:45:44,700 --> 00:45:49,490 In this example with the get handler, when we render down here, 784 00:45:49,490 --> 00:45:52,430 it's actually going to have to invoke that get handler function n 785 00:45:52,430 --> 00:45:54,320 times for n inputs. 786 00:45:54,320 --> 00:45:57,770 And so that means, if we have 1,000 inputs, 787 00:45:57,770 --> 00:46:00,500 it's going to have to evaluate that function 1000 times 788 00:46:00,500 --> 00:46:02,360 in order to get the handlers. 789 00:46:02,360 --> 00:46:08,720 And so if we instead define those as class properties, 790 00:46:08,720 --> 00:46:12,980 rather than invoking get handler 1,000 times for every render, 791 00:46:12,980 --> 00:46:15,250 it does it once when it creates the function. 792 00:46:15,250 --> 00:46:17,870 And then every render, it already has those class properties. 793 00:46:17,870 --> 00:46:20,690 It can just pass those straight through. 794 00:46:20,690 --> 00:46:25,100 And so even though using this get handler generic function, 795 00:46:25,100 --> 00:46:27,930 it's syntactically nicer, it's not necessarily more efficient. 796 00:46:27,930 --> 00:46:31,940 In fact, it's less efficient than defining all those handlers 797 00:46:31,940 --> 00:46:34,235 as class properties. 798 00:46:34,235 --> 00:46:37,400 And so whether you use a bunch of different class properties, 799 00:46:37,400 --> 00:46:40,940 or you use get handler here, depends on what you care more about. 800 00:46:40,940 --> 00:46:45,020 Do you care more about efficiency for reading and how nice it looks to read? 801 00:46:45,020 --> 00:46:48,071 Or do you care more about straight up efficiency and performance? 802 00:46:48,071 --> 00:46:50,720 803 00:46:50,720 --> 00:46:53,510 Of course, there are ways to do both. 804 00:46:53,510 --> 00:46:56,720 And if you're curious, go ahead and post your question in Slack, 805 00:46:56,720 --> 00:47:00,420 and I will answer it after the lecture. 806 00:47:00,420 --> 00:47:02,930 But let's go ahead and move onto the next topic for now. 807 00:47:02,930 --> 00:47:05,720 808 00:47:05,720 --> 00:47:06,590 So debugging. 809 00:47:06,590 --> 00:47:09,990 So there are a few different ways to debug. 810 00:47:09,990 --> 00:47:11,420 React and React native. 811 00:47:11,420 --> 00:47:14,960 Those are the React errors and warnings, Chrome developer tools. 812 00:47:14,960 --> 00:47:20,030 Or you may see some online documents referring to those as the "Devtools." 813 00:47:20,030 --> 00:47:22,220 This thing called a React native inspector. 814 00:47:22,220 --> 00:47:25,310 And this library called React dev tools. 815 00:47:25,310 --> 00:47:28,910 And so I'm curious to know how you guys have been debugging thus far. 816 00:47:28,910 --> 00:47:34,250 Go ahead and post in Slack your various workflows for debugging. 817 00:47:34,250 --> 00:47:38,870 I personally like to leave a bunch of console dot logs all over my files. 818 00:47:38,870 --> 00:47:43,790 And then go ahead and just look, oh, that's what the value of that variable 819 00:47:43,790 --> 00:47:45,470 was at that time. 820 00:47:45,470 --> 00:47:47,990 But that's probably not the best way for debugging. 821 00:47:47,990 --> 00:47:52,520 There are actually a bunch of tools that can do that and more. 822 00:47:52,520 --> 00:47:54,980 And one is React errors and warnings. 823 00:47:54,980 --> 00:47:58,150 And so you have this thing called console dot log, 824 00:47:58,150 --> 00:48:03,780 but it turns out that console object has other functions too. 825 00:48:03,780 --> 00:48:06,997 And so if you call this thing called console dot error, what happens 826 00:48:06,997 --> 00:48:08,330 is you get that full page alert. 827 00:48:08,330 --> 00:48:13,110 And so you've seen this a few times in lecture if we have an error, 828 00:48:13,110 --> 00:48:17,090 or if we trigger something In React that causes it to error out. 829 00:48:17,090 --> 00:48:20,620 And so you saw earlier when we had the infinite loop in component did update. 830 00:48:20,620 --> 00:48:27,440 And so we can go ahead and just trigger that manually by doing something like, 831 00:48:27,440 --> 00:48:32,750 in render we can just say, console dot air. 832 00:48:32,750 --> 00:48:35,000 This is a full page alert. 833 00:48:35,000 --> 00:48:38,470 834 00:48:38,470 --> 00:48:40,680 And so now when we go ahead and render that page, 835 00:48:40,680 --> 00:48:46,080 we see a whole red alert with our error at top. 836 00:48:46,080 --> 00:48:50,280 And it also nicely gives us a dump of the whole stack. 837 00:48:50,280 --> 00:48:53,390 So what were the functions that were called in order to get 838 00:48:53,390 --> 00:48:56,210 to that console dot alert function. 839 00:48:56,210 --> 00:48:59,390 840 00:48:59,390 --> 00:49:02,060 So another way to trigger this is also to just have an error, 841 00:49:02,060 --> 00:49:04,280 to throw an error. 842 00:49:04,280 --> 00:49:07,985 And so we can just do throw new error. 843 00:49:07,985 --> 00:49:14,850 844 00:49:14,850 --> 00:49:19,620 And when we throw that error, it's actually get caught by React 845 00:49:19,620 --> 00:49:24,780 and shown as this function, as this big red alert box. 846 00:49:24,780 --> 00:49:27,180 And, again, you see the stack trace where 847 00:49:27,180 --> 00:49:31,650 it was called in the add conduct forum. 848 00:49:31,650 --> 00:49:35,690 849 00:49:35,690 --> 00:49:38,690 So this is probably a very, very aggressive way to debug. 850 00:49:38,690 --> 00:49:41,945 And probably not the best way if you're playing with your application 851 00:49:41,945 --> 00:49:46,130 to just be greeted by a big, red alert. 852 00:49:46,130 --> 00:49:52,070 So there are also less aggressive ways by using these warnings. 853 00:49:52,070 --> 00:49:55,430 So a lot of libraries actually use either these full page alerts 854 00:49:55,430 --> 00:50:00,500 or these warnings to warn you or to alert you if something has gone wrong. 855 00:50:00,500 --> 00:50:03,410 And so where have we before seen yellow banners pop up? 856 00:50:03,410 --> 00:50:05,932 857 00:50:05,932 --> 00:50:07,140 Well it happens in prop type. 858 00:50:07,140 --> 00:50:10,760 So if we define some prop types for our function. 859 00:50:10,760 --> 00:50:13,747 And if we don't get the prop that we're expecting, 860 00:50:13,747 --> 00:50:15,830 that prop type's library written by [? Facebook ?] 861 00:50:15,830 --> 00:50:17,080 will give us a little warning. 862 00:50:17,080 --> 00:50:19,670 It says, hey, by the way, we were expecting a different type 863 00:50:19,670 --> 00:50:23,390 for the props and we got this. 864 00:50:23,390 --> 00:50:25,250 And so that shouldn't really be a big error, 865 00:50:25,250 --> 00:50:28,840 but they're just warning you, hey, by the way, this is happening. 866 00:50:28,840 --> 00:50:30,240 And how do they do that? 867 00:50:30,240 --> 00:50:32,285 Well, they call this cancel dot warn function. 868 00:50:32,285 --> 00:50:34,810 869 00:50:34,810 --> 00:50:41,840 And so, say, we want to just do console dot warn. 870 00:50:41,840 --> 00:50:46,370 This is a less aggressive warning. 871 00:50:46,370 --> 00:50:50,150 872 00:50:50,150 --> 00:50:53,810 And so when that gets called, we just get a small yellow box 873 00:50:53,810 --> 00:50:58,270 at the bottom that's letting us know that a warning appeared. 874 00:50:58,270 --> 00:51:02,600 875 00:51:02,600 --> 00:51:05,510 Again, maybe not things that you would use in your application. 876 00:51:05,510 --> 00:51:08,184 But if you're writing a library to be used by somebody else, 877 00:51:08,184 --> 00:51:10,850 you might want to warn them if they're using your library wrong. 878 00:51:10,850 --> 00:51:13,010 Or throw an error if an error does occur. 879 00:51:13,010 --> 00:51:15,590 880 00:51:15,590 --> 00:51:19,610 The caveat with these warnings is that they don't appear in production mode. 881 00:51:19,610 --> 00:51:23,104 And so if you have warnings, and you go ahead and deploy your app 882 00:51:23,104 --> 00:51:26,270 to the app store running in production mode, those warnings will not appear. 883 00:51:26,270 --> 00:51:29,750 884 00:51:29,750 --> 00:51:32,670 So this is not necessarily super useful. 885 00:51:32,670 --> 00:51:35,610 So what's a better way to debug rather than leaving console dot logs 886 00:51:35,610 --> 00:51:39,096 or leaving console dot errors or console dot warns. 887 00:51:39,096 --> 00:51:40,970 Well maybe we should use the Chrome Devtools. 888 00:51:40,970 --> 00:51:44,660 And so for those of you who have ever written web applications before, 889 00:51:44,660 --> 00:51:47,560 you might be familiar with these tools. 890 00:51:47,560 --> 00:51:53,750 So Google Chrome has amazing developer tools. 891 00:51:53,750 --> 00:51:55,070 Namely the debugger. 892 00:51:55,070 --> 00:51:58,460 And we'll take a look at that in a second. 893 00:51:58,460 --> 00:52:02,000 But if we're running a React native application, how the heck do 894 00:52:02,000 --> 00:52:03,620 we get Chrome Devtools to work? 895 00:52:03,620 --> 00:52:08,170 Isn't Chrome a web browser and aren't we trying to write mobile apps? 896 00:52:08,170 --> 00:52:13,460 Well if you remember back to early earlier on, 897 00:52:13,460 --> 00:52:16,280 we know that we can just run JavaScript in any Chrome tab. 898 00:52:16,280 --> 00:52:21,740 We know that we can also run JavaScript maybe in our terminal using Node.js. 899 00:52:21,740 --> 00:52:27,007 But how do we run React native JavaScript in Chrome? 900 00:52:27,007 --> 00:52:29,840 Well, if you remember back, there are actually two separate threads, 901 00:52:29,840 --> 00:52:32,822 one for native and one for JavaScript. 902 00:52:32,822 --> 00:52:34,280 And how do they talk to each other? 903 00:52:34,280 --> 00:52:37,250 Well they just communicate asynchronously through a bridge. 904 00:52:37,250 --> 00:52:40,760 Just sending messages back and forth like, hey, I need a button. 905 00:52:40,760 --> 00:52:42,860 And then the native will give you that button. 906 00:52:42,860 --> 00:52:47,950 And when it's clicked, it'll say, hey, JavaScript, my button was clicked. 907 00:52:47,950 --> 00:52:51,560 But does that mean they need to be running on the same device? 908 00:52:51,560 --> 00:52:53,219 Not necessarily. 909 00:52:53,219 --> 00:52:55,010 Since the way that they're communicating is 910 00:52:55,010 --> 00:52:57,860 just through this asynchronous message sending, 911 00:52:57,860 --> 00:53:01,490 that means we can run the native thread on that native device. 912 00:53:01,490 --> 00:53:03,380 And you can run the JavaScript anywhere. 913 00:53:03,380 --> 00:53:05,910 We can run it on the device. 914 00:53:05,910 --> 00:53:07,970 We can run it in a Chrome tab. 915 00:53:07,970 --> 00:53:12,020 We can even run it on somebody else's computer. 916 00:53:12,020 --> 00:53:15,560 And so we can actually go ahead and do that built 917 00:53:15,560 --> 00:53:20,580 into the React native application here. 918 00:53:20,580 --> 00:53:25,090 So I can go ahead and say, shake my device. 919 00:53:25,090 --> 00:53:32,000 So I can go to hardware shake, shake gesture, which is control command z. 920 00:53:32,000 --> 00:53:35,470 And it goes ahead and brings up this menu. 921 00:53:35,470 --> 00:53:39,270 And I can say, hey, I want to debug my JavaScript remotely. 922 00:53:39,270 --> 00:53:43,977 So if I click that, I get a new Chrome tab open. 923 00:53:43,977 --> 00:53:45,810 Then we just move this to a separate window. 924 00:53:45,810 --> 00:53:55,750 925 00:53:55,750 --> 00:53:58,100 So I now have a separate window. 926 00:53:58,100 --> 00:54:01,540 And if you look at the title here, it's saying React native debugger. 927 00:54:01,540 --> 00:54:03,880 And so the React native JavaScript code is running 928 00:54:03,880 --> 00:54:05,540 as a web worker inside this tab. 929 00:54:05,540 --> 00:54:09,875 Or in other words, the JavaScript is executing inside this Chrome tab. 930 00:54:09,875 --> 00:54:11,875 And I can go ahead and open the developer tools. 931 00:54:11,875 --> 00:54:20,660 932 00:54:20,660 --> 00:54:22,250 And I can see this. 933 00:54:22,250 --> 00:54:25,280 So if I go into debugger worker, local host 934 00:54:25,280 --> 00:54:32,930 1901, which is where this is running, I can go ahead and see all of this code. 935 00:54:32,930 --> 00:54:36,170 And if you look at something like add contact form, 936 00:54:36,170 --> 00:54:40,370 you see exactly what we have been working on recently. 937 00:54:40,370 --> 00:54:42,180 And so you see that get handler. 938 00:54:42,180 --> 00:54:44,791 Let me make the text bigger. 939 00:54:44,791 --> 00:54:49,660 940 00:54:49,660 --> 00:54:51,660 You see things that we've written very recently, 941 00:54:51,660 --> 00:54:53,034 like that get a handler function. 942 00:54:53,034 --> 00:54:57,540 That takes a key and returns a handler, a value, in that set state. 943 00:54:57,540 --> 00:55:02,280 And we can go ahead and use the power of Chrome's debugging tools to go ahead 944 00:55:02,280 --> 00:55:03,030 and debug our app. 945 00:55:03,030 --> 00:55:05,990 And so let's go ahead and throw a bug in our app and try to find. 946 00:55:05,990 --> 00:55:09,810 947 00:55:09,810 --> 00:55:16,085 So let's go ahead and rather than using this dot state dot name dot length 948 00:55:16,085 --> 00:55:19,550 to check name, let's try to enforce that the user have 949 00:55:19,550 --> 00:55:22,580 both a first name and a last name. 950 00:55:22,580 --> 00:55:27,420 And so let's use that in order to decide whether the form is valid or not. 951 00:55:27,420 --> 00:55:30,210 And so how might we do that? 952 00:55:30,210 --> 00:55:32,514 How do we check to see if the user has given us 953 00:55:32,514 --> 00:55:33,930 both a first name and a last name? 954 00:55:33,930 --> 00:55:37,410 955 00:55:37,410 --> 00:55:41,370 We can just count how many words are there, right? 956 00:55:41,370 --> 00:55:46,230 So let's go ahead and do something like content names 957 00:55:46,230 --> 00:55:50,590 are this dot state dot name dot split. 958 00:55:50,590 --> 00:55:53,230 And then split that every space. 959 00:55:53,230 --> 00:55:55,860 So for those of you who've never seen this dot split, 960 00:55:55,860 --> 00:55:59,040 it basically says with a string, given a string, 961 00:55:59,040 --> 00:56:04,290 every time you see whatever argument I pass in, go ahead and return 962 00:56:04,290 --> 00:56:09,930 to me an array that's tokenized by that character or string. 963 00:56:09,930 --> 00:56:12,330 And so in other words, every single time I see a string, 964 00:56:12,330 --> 00:56:15,630 give me the tokens around those strings. 965 00:56:15,630 --> 00:56:22,110 So in hello space world, give me an array containing hello and world. 966 00:56:22,110 --> 00:56:25,920 And so here, let's just assume that the user gives us a first name space 967 00:56:25,920 --> 00:56:27,120 last name. 968 00:56:27,120 --> 00:56:31,410 And now names will be an array of two names. 969 00:56:31,410 --> 00:56:33,870 The first name and the last name. 970 00:56:33,870 --> 00:56:41,940 And so now let's check if names dot length is greater than or equal to two. 971 00:56:41,940 --> 00:56:46,050 Then let's call that a valid name. 972 00:56:46,050 --> 00:56:49,510 Now down here let's get rid of all of those extraneous text inputs. 973 00:56:49,510 --> 00:56:59,690 974 00:56:59,690 --> 00:57:00,990 So delete here. 975 00:57:00,990 --> 00:57:04,330 976 00:57:04,330 --> 00:57:07,400 And now we're back to just those two things. 977 00:57:07,400 --> 00:57:10,200 And now we're using that get handler method. 978 00:57:10,200 --> 00:57:16,140 979 00:57:16,140 --> 00:57:18,190 So let's go ahead and try to add our name. 980 00:57:18,190 --> 00:57:24,470 981 00:57:24,470 --> 00:57:30,740 And make sure that the validation is running. 982 00:57:30,740 --> 00:57:33,980 So disable this dot state is valid form. 983 00:57:33,980 --> 00:57:35,210 The opposite of that. 984 00:57:35,210 --> 00:57:40,550 985 00:57:40,550 --> 00:57:43,340 So now hopefully we're in the state that we were before. 986 00:57:43,340 --> 00:57:48,890 Where the form starts invalid, and if I give it a valid phone number 987 00:57:48,890 --> 00:57:58,600 and a valid name, is it getting called? 988 00:57:58,600 --> 00:58:00,552 It must not be. 989 00:58:00,552 --> 00:58:05,920 990 00:58:05,920 --> 00:58:06,845 Component did update. 991 00:58:06,845 --> 00:58:08,328 This dot validate form. 992 00:58:08,328 --> 00:58:12,376 993 00:58:12,376 --> 00:58:14,250 So let's see if it's actually getting called. 994 00:58:14,250 --> 00:58:15,291 And how might we do that? 995 00:58:15,291 --> 00:58:17,470 So time to debug. 996 00:58:17,470 --> 00:58:21,900 So for those of you who've never used the debugger, what it allows us to do 997 00:58:21,900 --> 00:58:23,400 is set breakpoints. 998 00:58:23,400 --> 00:58:24,720 And what our breakpoints? 999 00:58:24,720 --> 00:58:26,850 Well, it's a point where, if this code path gets 1000 00:58:26,850 --> 00:58:30,360 hit, meaning if this code is about to get evaluated, stop and give me 1001 00:58:30,360 --> 00:58:32,980 a chance to look at some things. 1002 00:58:32,980 --> 00:58:39,420 And so we can go ahead and in that Devtools window, 1003 00:58:39,420 --> 00:58:48,450 we can say, hey, right before this gets called, let me stop in 1004 00:58:48,450 --> 00:58:49,500 and inspect some things. 1005 00:58:49,500 --> 00:58:50,940 Let me take a look around. 1006 00:58:50,940 --> 00:58:55,710 And so by clicking on these numbers around here, some things get called. 1007 00:58:55,710 --> 00:58:58,170 You see these blue highlights appear. 1008 00:58:58,170 --> 00:59:00,110 And that is me adding a breakpoint. 1009 00:59:00,110 --> 00:59:04,470 And so now, right before this line gets executed, it's actually going to pause 1010 00:59:04,470 --> 00:59:05,775 and let me look at some things. 1011 00:59:05,775 --> 00:59:09,030 1012 00:59:09,030 --> 00:59:12,290 So now let's make sure that gets triggered. 1013 00:59:12,290 --> 00:59:19,580 OK, so as soon as I change my name here, it triggered this. 1014 00:59:19,580 --> 00:59:22,910 And it says pause on breakpoint. 1015 00:59:22,910 --> 00:59:25,470 Now I can see the call stack, meaning what 1016 00:59:25,470 --> 00:59:30,970 are all of the functions called in order to get me to where I am now. 1017 00:59:30,970 --> 00:59:33,540 And so you see a lot of this is React internals. 1018 00:59:33,540 --> 00:59:36,530 But you see something that looks like this dot validate 1019 00:59:36,530 --> 00:59:40,590 form, which is from that add contact form that we were writing. 1020 00:59:40,590 --> 00:59:46,150 And so it makes sense that those were the most recent functions called. 1021 00:59:46,150 --> 00:59:47,190 And we also see scope. 1022 00:59:47,190 --> 00:59:50,110 We see all of the variables within our scope. 1023 00:59:50,110 --> 00:59:53,460 And so, if you remember back to earlier lectures, we talked about scope. 1024 00:59:53,460 --> 00:59:56,070 And scope being all of the variables that I 1025 00:59:56,070 --> 00:59:58,244 have access to at any given time. 1026 00:59:58,244 --> 01:00:00,910 And we see that names is currently undefined, which makes sense. 1027 01:00:00,910 --> 01:00:03,690 We haven't evaluated this line yet. 1028 01:00:03,690 --> 01:00:09,300 And we see some closures, which as you remember back a few lectures ago, 1029 01:00:09,300 --> 01:00:15,250 are functions that still have access to all of its parent-- 1030 01:00:15,250 --> 01:00:18,340 the variables in scope of its parent. 1031 01:00:18,340 --> 01:00:20,130 And so we see this add contact form, which 1032 01:00:20,130 --> 01:00:24,090 is this form that we're inside of. 1033 01:00:24,090 --> 01:00:26,490 And so we see all of the global variables 1034 01:00:26,490 --> 01:00:28,777 as well, which there are a ton. 1035 01:00:28,777 --> 01:00:30,610 But let's look at what we really care about. 1036 01:00:30,610 --> 01:00:33,880 We really care about names right now which is undefined. 1037 01:00:33,880 --> 01:00:36,690 And so we can say, hey, rather than-- we can click this button 1038 01:00:36,690 --> 01:00:37,710 to resume the execution. 1039 01:00:37,710 --> 01:00:39,960 So it'll just keep going. 1040 01:00:39,960 --> 01:00:42,330 Or we can just step over this next function call. 1041 01:00:42,330 --> 01:00:45,670 Or in other words, go to the next line. 1042 01:00:45,670 --> 01:00:47,950 We can also choose to go into the function. 1043 01:00:47,950 --> 01:00:50,700 If we want to, if we think, oh, it's not my code that's breaking, 1044 01:00:50,700 --> 01:00:53,310 it's actually this dot split code that's breaking, 1045 01:00:53,310 --> 01:00:57,210 I can choose to see how dot split is implemented. 1046 01:00:57,210 --> 01:01:01,080 But I think it's a safe assumption that the bug here is mine and not 1047 01:01:01,080 --> 01:01:02,380 the JavaScript's. 1048 01:01:02,380 --> 01:01:04,860 So I can say, OK, let's go to the next line. 1049 01:01:04,860 --> 01:01:08,340 And so now we see what's highlighted. 1050 01:01:08,340 --> 01:01:11,220 We know that line 57 has just gotten executed. 1051 01:01:11,220 --> 01:01:13,110 And we're about to execute line 58. 1052 01:01:13,110 --> 01:01:15,450 And so now what is in scope? 1053 01:01:15,450 --> 01:01:17,150 Well names get updated. 1054 01:01:17,150 --> 01:01:25,195 Now names is Jordan space hayash, which is what we were writing in the input. 1055 01:01:25,195 --> 01:01:27,570 And so now we can go ahead and step through our code line 1056 01:01:27,570 --> 01:01:29,790 by line to see where the bug is. 1057 01:01:29,790 --> 01:01:32,670 1058 01:01:32,670 --> 01:01:35,950 And so now we can go ahead and say, OK, we're checking phone, 1059 01:01:35,950 --> 01:01:38,840 we're checking phone's length, and we're checking names dot length. 1060 01:01:38,840 --> 01:01:42,600 1061 01:01:42,600 --> 01:01:44,400 And so this worked. 1062 01:01:44,400 --> 01:01:46,950 And so now we're on line 59. 1063 01:01:46,950 --> 01:01:50,880 And it's about to say, is form valid true. 1064 01:01:50,880 --> 01:01:53,400 Cool. 1065 01:01:53,400 --> 01:01:57,190 Click next and then what is happening now? 1066 01:01:57,190 --> 01:01:59,050 So now, it updated everything. 1067 01:01:59,050 --> 01:02:01,430 And now we're in the next cycle. 1068 01:02:01,430 --> 01:02:02,930 So it was validating the form again. 1069 01:02:02,930 --> 01:02:05,572 And so we can just keep clicking through. 1070 01:02:05,572 --> 01:02:09,820 1071 01:02:09,820 --> 01:02:11,550 And now the component did update is done. 1072 01:02:11,550 --> 01:02:13,937 And so this dot validate form is finished. 1073 01:02:13,937 --> 01:02:15,520 And now it's going to finish updating. 1074 01:02:15,520 --> 01:02:19,030 And we can just hit play. 1075 01:02:19,030 --> 01:02:22,110 It looks like we're stuck in a loop. 1076 01:02:22,110 --> 01:02:24,070 What's happening over here? 1077 01:02:24,070 --> 01:02:29,940 1078 01:02:29,940 --> 01:02:30,440 OK. 1079 01:02:30,440 --> 01:02:33,870 1080 01:02:33,870 --> 01:02:36,620 So we saw that the problem was not in this validate form. 1081 01:02:36,620 --> 01:02:40,590 Names was getting set to be what we thought it was being set to. 1082 01:02:40,590 --> 01:02:42,590 And we saw that this dot set state is form 1083 01:02:42,590 --> 01:02:45,360 valid is getting updated to be true. 1084 01:02:45,360 --> 01:02:47,970 And so the bug lies somewhere else. 1085 01:02:47,970 --> 01:02:51,160 So is form valid is getting updated as expected. 1086 01:02:51,160 --> 01:02:57,000 And so down here, we see why isn't disabled getting updated? 1087 01:02:57,000 --> 01:03:01,012 Well this dot state is valid form does not exist. 1088 01:03:01,012 --> 01:03:01,970 What are we calling it? 1089 01:03:01,970 --> 01:03:06,630 Well we're calling it this dot state dot is formed valid. 1090 01:03:06,630 --> 01:03:15,960 1091 01:03:15,960 --> 01:03:18,340 So we see up in the state, we're declaring is form valid. 1092 01:03:18,340 --> 01:03:19,770 We're updating here. 1093 01:03:19,770 --> 01:03:23,820 And that is what we should be looking at, rather than is valid form. 1094 01:03:23,820 --> 01:03:28,370 Cool so we caught the bug. 1095 01:03:28,370 --> 01:03:31,760 And now we can ensure that it works. 1096 01:03:31,760 --> 01:03:36,480 1097 01:03:36,480 --> 01:03:39,060 Great, now it worked. 1098 01:03:39,060 --> 01:03:40,820 But let's say, oh, I made a typo. 1099 01:03:40,820 --> 01:03:42,050 Let me go back. 1100 01:03:42,050 --> 01:03:46,520 Hey, wait a second, is there a first name and a last name? 1101 01:03:46,520 --> 01:03:49,100 No, but it's saying that the form is still valid. 1102 01:03:49,100 --> 01:03:51,050 And so now we have another bug. 1103 01:03:51,050 --> 01:03:53,390 And so let's now go use Chrome Devtools again 1104 01:03:53,390 --> 01:03:56,810 to figure out what the bug is here. 1105 01:03:56,810 --> 01:03:59,840 So let's again set a breakpoint here. 1106 01:03:59,840 --> 01:04:10,990 And go ahead and find that case. 1107 01:04:10,990 --> 01:04:18,905 1108 01:04:18,905 --> 01:04:19,405 OK. 1109 01:04:19,405 --> 01:04:31,320 1110 01:04:31,320 --> 01:04:34,310 And now when we hit a space, now we're back to where we were. 1111 01:04:34,310 --> 01:04:37,860 On the case that has been tripping us up. 1112 01:04:37,860 --> 01:04:39,740 And so now, we're about to execute line 57. 1113 01:04:39,740 --> 01:04:42,010 We see names is undefined. 1114 01:04:42,010 --> 01:04:46,520 And so let's go ahead and execute that line. 1115 01:04:46,520 --> 01:04:48,702 And now we see names of length 2. 1116 01:04:48,702 --> 01:04:49,660 And what is that array? 1117 01:04:49,660 --> 01:04:52,730 1118 01:04:52,730 --> 01:04:57,420 Well the first name is Jordan and that second string does not exist. 1119 01:04:57,420 --> 01:05:01,550 And so names dot split is doing what we're telling it to. 1120 01:05:01,550 --> 01:05:04,340 We're saying split at every space. 1121 01:05:04,340 --> 01:05:11,210 And right now, this dot state dot name, we could dig for it in here. 1122 01:05:11,210 --> 01:05:19,520 So this dot state dot name is Jordan space, which 1123 01:05:19,520 --> 01:05:21,780 isn't a first and last name pair. 1124 01:05:21,780 --> 01:05:27,350 But the way that we're defining whether or not a name is of length two 1125 01:05:27,350 --> 01:05:28,910 is getting fired. 1126 01:05:28,910 --> 01:05:34,670 So, again, this dot state dot name is Jordan space. 1127 01:05:34,670 --> 01:05:40,550 And we see that name dot split at the space is giving us two entries. 1128 01:05:40,550 --> 01:05:42,740 Jordan and empty stream. 1129 01:05:42,740 --> 01:05:44,766 Because it is splitting at the space. 1130 01:05:44,766 --> 01:05:45,890 And what's after the space? 1131 01:05:45,890 --> 01:05:48,200 Well, an empty string. 1132 01:05:48,200 --> 01:05:53,290 And so we see that here, this is returning true when it should not be. 1133 01:05:53,290 --> 01:05:57,050 And so now we can go ahead and fix that bug. 1134 01:05:57,050 --> 01:06:05,501 So rather than saying names dot length is greater than or equal to 2, 1135 01:06:05,501 --> 01:06:06,750 what do we have to do instead? 1136 01:06:06,750 --> 01:06:10,440 1137 01:06:10,440 --> 01:06:14,175 We should also check that names-- 1138 01:06:14,175 --> 01:06:17,850 1139 01:06:17,850 --> 01:06:20,280 the last name exists. 1140 01:06:20,280 --> 01:06:24,070 And so we can just do, hey, remember back to what are all the falsy values. 1141 01:06:24,070 --> 01:06:26,350 Well empty string is a falsy value. 1142 01:06:26,350 --> 01:06:33,060 And so if names bracket one, meaning the last name, if that's an empty string 1143 01:06:33,060 --> 01:06:37,070 that shouldn't be an accepted value. 1144 01:06:37,070 --> 01:06:39,626 And so now let's go ahead and remove that breakpoint. 1145 01:06:39,626 --> 01:06:54,206 1146 01:06:54,206 --> 01:07:03,120 So we are in the file called add contact form. 1147 01:07:03,120 --> 01:07:05,640 Let's go ahead and remove that breakpoint. 1148 01:07:05,640 --> 01:07:09,590 And now we see that if I do Jordan space. 1149 01:07:09,590 --> 01:07:11,850 Well this isn't a valid phone number. 1150 01:07:11,850 --> 01:07:15,715 Jordan space, it's still erroring. 1151 01:07:15,715 --> 01:07:16,715 Did we remember to save? 1152 01:07:16,715 --> 01:07:19,600 1153 01:07:19,600 --> 01:07:20,250 We did not. 1154 01:07:20,250 --> 01:07:25,620 So, again, phone number, Jordan space. 1155 01:07:25,620 --> 01:07:27,080 And it is not a valid form. 1156 01:07:27,080 --> 01:07:30,010 1157 01:07:30,010 --> 01:07:32,550 And so we can use Chrome's debugger tools 1158 01:07:32,550 --> 01:07:35,592 to go ahead and step through our code line by line 1159 01:07:35,592 --> 01:07:37,550 and see all of the variables that are in scope. 1160 01:07:37,550 --> 01:07:41,370 And so we can catch bugs like this, where what we think 1161 01:07:41,370 --> 01:07:44,720 is the case that we're looking for, might not be. 1162 01:07:44,720 --> 01:07:47,011 And actually it's still slightly buggy. 1163 01:07:47,011 --> 01:07:48,010 Can anybody see the bug? 1164 01:07:48,010 --> 01:07:56,222 1165 01:07:56,222 --> 01:07:58,930 So if we have a leading space, we're only checking the last name. 1166 01:07:58,930 --> 01:08:01,620 We're not making sure the first name is existing. 1167 01:08:01,620 --> 01:08:05,320 And so we can fix that real quick. 1168 01:08:05,320 --> 01:08:10,770 We can say, oh names zero also needs to exist. 1169 01:08:10,770 --> 01:08:13,570 And we'll call that good enough. 1170 01:08:13,570 --> 01:08:20,859 So now with a valid phone number, space [? Hayashi ?] doesn't work. 1171 01:08:20,859 --> 01:08:23,310 Space space doesn't work. 1172 01:08:23,310 --> 01:08:27,974 And it only works as soon as we start to add that second value. 1173 01:08:27,974 --> 01:08:33,880 1174 01:08:33,880 --> 01:08:39,220 And so another great thing about Chrome developer tools is the console. 1175 01:08:39,220 --> 01:08:42,220 And so I said earlier how I love console dot log. 1176 01:08:42,220 --> 01:08:45,550 And let's actually look at a case where console dot log works in the browser. 1177 01:08:45,550 --> 01:08:50,580 But it might not work in other environments. 1178 01:08:50,580 --> 01:08:52,840 So let's go ahead and stop remote debugging. 1179 01:08:52,840 --> 01:08:58,500 And so now we're running the JavaScript not in the browser. 1180 01:08:58,500 --> 01:09:02,800 And so let's go ahead and every time we want to validate the form, 1181 01:09:02,800 --> 01:09:04,350 let's just console dot log the form. 1182 01:09:04,350 --> 01:09:05,100 Or this dot state. 1183 01:09:05,100 --> 01:09:11,510 1184 01:09:11,510 --> 01:09:17,180 So now when we're changing the state, we see things are updating over here. 1185 01:09:17,180 --> 01:09:20,990 And so the logging of the JavaScript is getting piped over 1186 01:09:20,990 --> 01:09:24,140 to the [? expo XTE. ?] And we see down here, 1187 01:09:24,140 --> 01:09:26,689 when we console log this dot state, we see 1188 01:09:26,689 --> 01:09:29,779 an object that has all of the keys and values of state. 1189 01:09:29,779 --> 01:09:35,270 Where is form valid is false, name is Jay, and phone is empty string. 1190 01:09:35,270 --> 01:09:40,712 But what happens if that object is pretty complicated? 1191 01:09:40,712 --> 01:09:43,670 1192 01:09:43,670 --> 01:09:46,060 What happens if that object has a cycle? 1193 01:09:46,060 --> 01:09:51,025 1194 01:09:51,025 --> 01:09:56,930 So now we're sticking inside of state this is equal to this. 1195 01:09:56,930 --> 01:10:00,430 And so this here, is going to have this dot state in it. 1196 01:10:00,430 --> 01:10:04,410 And so this dot state dot this, is going to be this. 1197 01:10:04,410 --> 01:10:08,850 Do you see how this is going to start becoming circular? 1198 01:10:08,850 --> 01:10:11,290 And so this is called circular JSON. 1199 01:10:11,290 --> 01:10:16,010 Or JavaScript object that self-references itself. 1200 01:10:16,010 --> 01:10:21,880 And so now if we start to type anything here, things just aren't going to work. 1201 01:10:21,880 --> 01:10:26,900 1202 01:10:26,900 --> 01:10:28,990 So this is now a valid form. 1203 01:10:28,990 --> 01:10:33,910 But it's not showing as a valid form. 1204 01:10:33,910 --> 01:10:35,170 Why? 1205 01:10:35,170 --> 01:10:40,670 Because this initial console dot log is still trying to happen. 1206 01:10:40,670 --> 01:10:43,325 And so you notice that nothing here is getting logged. 1207 01:10:43,325 --> 01:10:45,700 It's because it's still trying to figure out what to log. 1208 01:10:45,700 --> 01:10:47,410 It's going through that infinite cycle. 1209 01:10:47,410 --> 01:10:51,530 1210 01:10:51,530 --> 01:11:00,970 But, it turns out if we try to actually do this in the browser instead, 1211 01:11:00,970 --> 01:11:04,140 so now we're back here. 1212 01:11:04,140 --> 01:11:05,490 Say we type something over here. 1213 01:11:05,490 --> 01:11:08,690 1214 01:11:08,690 --> 01:11:09,560 It works. 1215 01:11:09,560 --> 01:11:14,420 And so Chrome's logging abilities are actually phenomenal. 1216 01:11:14,420 --> 01:11:17,630 And you can see that it gets printed four times because we 1217 01:11:17,630 --> 01:11:19,550 changed the value four times. 1218 01:11:19,550 --> 01:11:21,040 And what do we see here? 1219 01:11:21,040 --> 01:11:25,040 We see is form valid false, name, test, phone, empty string as expected. 1220 01:11:25,040 --> 01:11:27,920 And then we see this. 1221 01:11:27,920 --> 01:11:30,440 Which has in it, this dot state, which has 1222 01:11:30,440 --> 01:11:35,000 in it this, which has in it this dot state, which has in it this. 1223 01:11:35,000 --> 01:11:37,920 And this can go on forever. 1224 01:11:37,920 --> 01:11:42,080 And so the logging abilities of Chrome are actually pretty incredible. 1225 01:11:42,080 --> 01:11:45,320 As are the debugger. 1226 01:11:45,320 --> 01:11:48,110 And so this is a great way to go ahead and debug. 1227 01:11:48,110 --> 01:11:50,100 You can step through your code line by line. 1228 01:11:50,100 --> 01:11:52,970 You can have these pretty complex console dot logs and it all works. 1229 01:11:52,970 --> 01:11:59,070 1230 01:11:59,070 --> 01:12:01,250 So what happens if the bug is not logical? 1231 01:12:01,250 --> 01:12:05,715 What happens if the bug is rather in the layout? 1232 01:12:05,715 --> 01:12:09,347 1233 01:12:09,347 --> 01:12:10,680 So let me introduce a small bug. 1234 01:12:10,680 --> 01:12:18,160 1235 01:12:18,160 --> 01:12:21,530 So let's actually go ahead and stop running this remotely. 1236 01:12:21,530 --> 01:12:33,310 1237 01:12:33,310 --> 01:12:36,780 So now we have our form. 1238 01:12:36,780 --> 01:12:39,930 It's at the top like it was at the beginning. 1239 01:12:39,930 --> 01:12:43,570 And say now we want to try to get it to the center. 1240 01:12:43,570 --> 01:12:46,012 Let's try to center this form vertically. 1241 01:12:46,012 --> 01:12:49,940 1242 01:12:49,940 --> 01:12:55,640 The way you would do that would be justify content into the center. 1243 01:12:55,640 --> 01:12:57,790 And that, in theory, is going to take all 1244 01:12:57,790 --> 01:13:03,837 of the content of the container, which is what we're calling the wrapper, 1245 01:13:03,837 --> 01:13:06,170 and move all of its content to the center of its height. 1246 01:13:06,170 --> 01:13:08,960 1247 01:13:08,960 --> 01:13:12,360 But as we see, it's not moving down to the center. 1248 01:13:12,360 --> 01:13:14,640 And those of you-- 1249 01:13:14,640 --> 01:13:18,350 some people may see instantly, oh exactly what's wrong. 1250 01:13:18,350 --> 01:13:20,220 But it's pretty not obvious. 1251 01:13:20,220 --> 01:13:23,970 We have it supposedly centering. 1252 01:13:23,970 --> 01:13:29,300 But it's not moving to the center of the screen like we're expecting. 1253 01:13:29,300 --> 01:13:33,300 And so this is not really something you can debug using the Devtools 1254 01:13:33,300 --> 01:13:35,760 or console dot log, because it's not a logical bug. 1255 01:13:35,760 --> 01:13:37,720 This one has to do with layout. 1256 01:13:37,720 --> 01:13:44,500 And so it would be really great if we could just inspect all of the layouts. 1257 01:13:44,500 --> 01:13:48,160 Fortunately, we have something called the React native inspector. 1258 01:13:48,160 --> 01:13:50,840 And this is analogous to that Chrome element inspector. 1259 01:13:50,840 --> 01:13:54,970 So those of you with a web background, probably use that element inspector 1260 01:13:54,970 --> 01:13:58,510 where you can see all of the Dom elements, 1261 01:13:58,510 --> 01:14:03,307 and see exactly where they are on the page. 1262 01:14:03,307 --> 01:14:05,890 It also allows you to see data associated with those elements, 1263 01:14:05,890 --> 01:14:10,030 like margin, padding, size, et cetera. 1264 01:14:10,030 --> 01:14:11,472 And so we can actually go ahead-- 1265 01:14:11,472 --> 01:14:13,930 we can use that tool to figure out what's going wrong here. 1266 01:14:13,930 --> 01:14:15,750 And so, again, if we shake our device, we 1267 01:14:15,750 --> 01:14:19,740 can see this toggle element inspector button. 1268 01:14:19,740 --> 01:14:23,330 And if you click on it, we see this UI pop up. 1269 01:14:23,330 --> 01:14:27,270 It says tap something to inspect it. 1270 01:14:27,270 --> 01:14:32,647 And so if we go and click this inspect button down here, that will toggle on. 1271 01:14:32,647 --> 01:14:34,480 And so now we can click anywhere, and we can 1272 01:14:34,480 --> 01:14:37,990 start to see all of the styles associated with something. 1273 01:14:37,990 --> 01:14:45,620 So say we click on this input, we see down here 1274 01:14:45,620 --> 01:14:49,320 this text input is in add contact form.js, which 1275 01:14:49,320 --> 01:14:52,530 is exactly where we defined it. 1276 01:14:52,530 --> 01:14:53,972 We see all of it style attributes. 1277 01:14:53,972 --> 01:14:55,180 It has a border width of one. 1278 01:14:55,180 --> 01:15:00,550 It has a border color black, mid width 100, margin top 20, et cetera. 1279 01:15:00,550 --> 01:15:03,100 And we see exactly how it's laid out. 1280 01:15:03,100 --> 01:15:05,020 And so imagine that this was a box. 1281 01:15:05,020 --> 01:15:06,480 We see its margins. 1282 01:15:06,480 --> 01:15:09,150 So it has a margin top of 20. 1283 01:15:09,150 --> 01:15:10,410 Bottom, there's no margin. 1284 01:15:10,410 --> 01:15:12,530 And on either side it's 20. 1285 01:15:12,530 --> 01:15:13,830 We see some padding. 1286 01:15:13,830 --> 01:15:18,080 And we see the dimensions of the element itself. 1287 01:15:18,080 --> 01:15:19,830 And so that's helpful information as we're 1288 01:15:19,830 --> 01:15:25,642 trying to determine how are we trying to lay out our UI elements. 1289 01:15:25,642 --> 01:15:26,850 And so what's the buggy part? 1290 01:15:26,850 --> 01:15:31,870 The buggy part is that form that we say, oh, it should be centering its content 1291 01:15:31,870 --> 01:15:32,880 but it's not. 1292 01:15:32,880 --> 01:15:34,650 And so let's go ahead and find that form. 1293 01:15:34,650 --> 01:15:37,090 The submit button. 1294 01:15:37,090 --> 01:15:41,430 There's that form. 1295 01:15:41,430 --> 01:15:49,522 This is the keyboard avoiding view in the add contact form. 1296 01:15:49,522 --> 01:15:53,100 So it has a background color of white, has a padding top 1297 01:15:53,100 --> 01:15:56,370 of 20, justified content center, padding bottom 0, all these things 1298 01:15:56,370 --> 01:15:58,800 that we defined in the style. 1299 01:15:58,800 --> 01:16:01,710 But the height isn't what we're expecting. 1300 01:16:01,710 --> 01:16:07,380 We're expecting it to be full height, but what's being highlighted 1301 01:16:07,380 --> 01:16:10,530 is only this here. 1302 01:16:10,530 --> 01:16:13,150 And so blue refers to the height of the element itself. 1303 01:16:13,150 --> 01:16:16,720 Green refers to its padding. 1304 01:16:16,720 --> 01:16:22,390 And so it is centering its content. 1305 01:16:22,390 --> 01:16:25,840 If you imagine the height is here, everything is perfectly centered. 1306 01:16:25,840 --> 01:16:28,540 It's just the height is not what we were expecting it to be. 1307 01:16:28,540 --> 01:16:32,460 We thought the height was going to be the full and so center should be here. 1308 01:16:32,460 --> 01:16:33,460 And so we found our bug. 1309 01:16:33,460 --> 01:16:37,870 The bug is that we just need to make the height full height, 1310 01:16:37,870 --> 01:16:40,550 so that when it's entering its content, the content 1311 01:16:40,550 --> 01:16:42,190 is in the center of the device. 1312 01:16:42,190 --> 01:16:44,890 Not the center of this view, which is not as tall as we thought. 1313 01:16:44,890 --> 01:16:47,720 1314 01:16:47,720 --> 01:16:54,590 And so if you remember back to section when you guys talked about Flexbox, 1315 01:16:54,590 --> 01:16:55,540 we can see the bug. 1316 01:16:55,540 --> 01:16:58,570 So a container should be filling all of its available space. 1317 01:16:58,570 --> 01:17:01,040 We should say flex 1. 1318 01:17:01,040 --> 01:17:02,720 So grow as much as you can. 1319 01:17:02,720 --> 01:17:06,094 1320 01:17:06,094 --> 01:17:10,820 And now, it's centered again. 1321 01:17:10,820 --> 01:17:12,000 And how can we confirm that? 1322 01:17:12,000 --> 01:17:14,360 Well, we can click on that add contact form 1323 01:17:14,360 --> 01:17:17,810 and now we see it's blue all the way down. 1324 01:17:17,810 --> 01:17:19,940 And we see the height is now what we expected. 1325 01:17:19,940 --> 01:17:22,640 1326 01:17:22,640 --> 01:17:27,260 And so for testing UI elements and seeing exactly how they're laid out, 1327 01:17:27,260 --> 01:17:30,400 their size, their padding, their margin, the inspector 1328 01:17:30,400 --> 01:17:32,990 is a great tool to be able to do that. 1329 01:17:32,990 --> 01:17:35,880 1330 01:17:35,880 --> 01:17:39,410 The caveat with this inspector is that doesn't 1331 01:17:39,410 --> 01:17:41,330 allow you to live edit these elements. 1332 01:17:41,330 --> 01:17:45,250 So when I wanted to change the flex to be one, 1333 01:17:45,250 --> 01:17:47,000 I actually had to go do that in the source 1334 01:17:47,000 --> 01:17:51,830 I had to rebundle the JavaScript, have the bundle get sent to the app, 1335 01:17:51,830 --> 01:17:53,670 and have app reload. 1336 01:17:53,670 --> 01:17:57,924 It doesn't allow me to just hop in there and change things at will. 1337 01:17:57,924 --> 01:17:59,840 Since I'm talking about that, you can probably 1338 01:17:59,840 --> 01:18:01,340 guess there is a tool to do that. 1339 01:18:01,340 --> 01:18:04,117 That tool is called React dev tools. 1340 01:18:04,117 --> 01:18:06,575 This allows you to inspect the React component hierarchies, 1341 01:18:06,575 --> 01:18:11,990 so you can see the entire React tree including the components, the props 1342 01:18:11,990 --> 01:18:15,939 and its state, style. 1343 01:18:15,939 --> 01:18:16,730 How do we run this? 1344 01:18:16,730 --> 01:18:19,290 So first we have to install it. 1345 01:18:19,290 --> 01:18:24,040 So if you run this command npm install -g, which stands for globally. 1346 01:18:24,040 --> 01:18:27,690 Install this library called React dev tools. 1347 01:18:27,690 --> 01:18:36,130 And so we can go ahead and do an npm install -g react dev tools. 1348 01:18:36,130 --> 01:18:39,796 So I already have it installed, so it's going to happen fairly quickly. 1349 01:18:39,796 --> 01:18:42,170 But for those of you at home who don't have it installed, 1350 01:18:42,170 --> 01:18:45,590 you can go ahead and install it globally now. 1351 01:18:45,590 --> 01:18:49,310 And this will allow us to go ahead and use this tool called React dev 1352 01:18:49,310 --> 01:18:52,850 tools anywhere. 1353 01:18:52,850 --> 01:18:56,630 And so when we want to run it, all we have to do is type React dev tools, 1354 01:18:56,630 --> 01:19:01,956 and it will open up, it will run the command, and open it up. 1355 01:19:01,956 --> 01:19:04,580 And what that does is it allows us to make live edits to style, 1356 01:19:04,580 --> 01:19:07,430 live edits to props, et cetera. 1357 01:19:07,430 --> 01:19:11,090 And if you want to read more about it, you can go to its Github page. 1358 01:19:11,090 --> 01:19:13,060 It's also maintained by Facebook. 1359 01:19:13,060 --> 01:19:14,850 I mean, it's a brilliant tool. 1360 01:19:14,850 --> 01:19:16,758 So go ahead and give it a shot. 1361 01:19:16,758 --> 01:19:22,220 1362 01:19:22,220 --> 01:19:24,370 So notice we just run it as React dev tools. 1363 01:19:24,370 --> 01:19:26,200 We don't have to tell it where our app is. 1364 01:19:26,200 --> 01:19:29,950 And it will just go ahead and find our application. 1365 01:19:29,950 --> 01:19:36,192 And so now we see this. 1366 01:19:36,192 --> 01:19:43,080 1367 01:19:43,080 --> 01:19:45,270 We see app container. 1368 01:19:45,270 --> 01:19:47,720 And if we start to unfold these things, things 1369 01:19:47,720 --> 01:19:54,229 are going to start become pretty recognizable. 1370 01:19:54,229 --> 01:19:56,270 So we're starting to see things that we've named. 1371 01:19:56,270 --> 01:20:01,390 Add contact form, app, text input, text input button. 1372 01:20:01,390 --> 01:20:07,071 And as we hover over them, you can see them highlight over here. 1373 01:20:07,071 --> 01:20:08,070 And how is that working? 1374 01:20:08,070 --> 01:20:11,244 Well it's actually working with the inspector to do that. 1375 01:20:11,244 --> 01:20:14,155 1376 01:20:14,155 --> 01:20:16,280 And so now let's go ahead and reintroduce that bug. 1377 01:20:16,280 --> 01:20:34,900 1378 01:20:34,900 --> 01:20:38,650 Let's go ahead and reintroduce that bug into add contact form. 1379 01:20:38,650 --> 01:20:40,120 We can get rid of that flex. 1380 01:20:40,120 --> 01:20:44,190 Let's get rid of justify content center as well. 1381 01:20:44,190 --> 01:20:50,500 And so now we're back to where we started, with that original bug, 1382 01:20:50,500 --> 01:20:55,840 where we want to center this and we're going to have to figure out how. 1383 01:20:55,840 --> 01:20:59,669 And so let's do that in the React developer tools. 1384 01:20:59,669 --> 01:21:10,930 And so you can see that this tree here matches up exactly with the tree 1385 01:21:10,930 --> 01:21:12,610 that we've defined in our code. 1386 01:21:12,610 --> 01:21:15,400 And this is actually the react element tree. 1387 01:21:15,400 --> 01:21:17,440 And so we can find that keyboard avoiding view, 1388 01:21:17,440 --> 01:21:19,180 and we can see the style here. 1389 01:21:19,180 --> 01:21:22,500 We see background colors FFF and padding top is 20. 1390 01:21:22,500 --> 01:21:26,170 And that matches with exactly what we have here where 20 is just 1391 01:21:26,170 --> 01:21:29,870 getting the value of this variable. 1392 01:21:29,870 --> 01:21:32,380 1393 01:21:32,380 --> 01:21:35,830 And so now we can actually add inline whatever we want. 1394 01:21:35,830 --> 01:21:43,530 We can say, right now if we highlight over this with the inspector on, 1395 01:21:43,530 --> 01:21:47,040 we see that this keyboard avoiding view is only this tall. 1396 01:21:47,040 --> 01:21:49,610 It's only as tall as its content. 1397 01:21:49,610 --> 01:21:51,750 And so let's first get that to fill. 1398 01:21:51,750 --> 01:21:57,450 And so we can go ahead and just say, oh, I wonder what's going wrong. 1399 01:21:57,450 --> 01:22:02,430 Let me add flex one. 1400 01:22:02,430 --> 01:22:05,010 And so now, all of a sudden, keyboard avoiding view 1401 01:22:05,010 --> 01:22:07,050 is filling all the available space. 1402 01:22:07,050 --> 01:22:08,925 Which is exactly what we're telling it to do. 1403 01:22:08,925 --> 01:22:13,340 We're saying, flex grow until you fill all of the available space. 1404 01:22:13,340 --> 01:22:16,160 So now we can go ahead and center all of its content. 1405 01:22:16,160 --> 01:22:18,910 And we can say justify your content to the center. 1406 01:22:18,910 --> 01:22:23,320 1407 01:22:23,320 --> 01:22:25,060 And you see it jumps immediately. 1408 01:22:25,060 --> 01:22:30,340 1409 01:22:30,340 --> 01:22:34,120 And so this also allows us to inspect all of our components. 1410 01:22:34,120 --> 01:22:37,210 State, our props, anything that we care about. 1411 01:22:37,210 --> 01:22:45,050 And so right now inside our form so, say we can't find our form. 1412 01:22:45,050 --> 01:22:46,130 Say it's buried deep. 1413 01:22:46,130 --> 01:22:50,320 We can just go ahead and search form and we find or add conduct form. 1414 01:22:50,320 --> 01:22:53,710 And you can see its subtree here. 1415 01:22:53,710 --> 01:22:57,010 Right now its state is saying is form valid false, name, phone. 1416 01:22:57,010 --> 01:23:11,120 And as we change things, you can see things live update over here. 1417 01:23:11,120 --> 01:23:15,150 And so as the state of the app changes, you can see it update in the dev tools 1418 01:23:15,150 --> 01:23:15,650 here. 1419 01:23:15,650 --> 01:23:18,890 And so this is a great tool to make sure what 1420 01:23:18,890 --> 01:23:22,790 you think is happening to the state is exactly what's happening to the state. 1421 01:23:22,790 --> 01:23:24,510 And you can even override this. 1422 01:23:24,510 --> 01:23:28,290 Let's say the phone should be this. 1423 01:23:28,290 --> 01:23:32,210 And it will go ahead and set that state for you. 1424 01:23:32,210 --> 01:23:37,730 So this is all around great tool for inspecting state, setting state, making 1425 01:23:37,730 --> 01:23:40,670 sure things happen when you set state. 1426 01:23:40,670 --> 01:23:44,060 You can go ahead and inspect style and go ahead and quickly prototype, 1427 01:23:44,060 --> 01:23:49,640 so that you don't have to type all of your style into your text editor. 1428 01:23:49,640 --> 01:23:53,670 You can just see exactly how it's going to impact your application. 1429 01:23:53,670 --> 01:23:56,060 And then if you like what you see then go ahead and then 1430 01:23:56,060 --> 01:23:58,550 commit that and save it in your text editor. 1431 01:23:58,550 --> 01:24:00,830 You can also see what props are coming down. 1432 01:24:00,830 --> 01:24:04,170 You can ensure that you're passing the props that you think are passing down. 1433 01:24:04,170 --> 01:24:05,920 I mean, so this is just a great tool to be 1434 01:24:05,920 --> 01:24:07,490 able to see exactly what React knows. 1435 01:24:07,490 --> 01:24:11,950 1436 01:24:11,950 --> 01:24:17,320 So any questions on React dev tools, the inspector, or Chrome Devtools? 1437 01:24:17,320 --> 01:24:23,320 1438 01:24:23,320 --> 01:24:24,810 So let's move on to our last topic. 1439 01:24:24,810 --> 01:24:27,400 So external library. 1440 01:24:27,400 --> 01:24:30,940 So how did we get React dev tools onto our computer? 1441 01:24:30,940 --> 01:24:34,600 We use this thing called NPM And React dev tools is actually 1442 01:24:34,600 --> 01:24:36,970 just an external library, external code that we're 1443 01:24:36,970 --> 01:24:39,140 bringing into our own project. 1444 01:24:39,140 --> 01:24:42,042 So libraries are code written outside the context of your project, 1445 01:24:42,042 --> 01:24:43,750 that you can bring into your own project. 1446 01:24:43,750 --> 01:24:47,980 And so these can be written by you, they can be written by other people, 1447 01:24:47,980 --> 01:24:49,690 or they can be written by companies. 1448 01:24:49,690 --> 01:24:51,160 Or anybody really. 1449 01:24:51,160 --> 01:24:53,900 And so stuff like React is a library. 1450 01:24:53,900 --> 01:24:56,950 It's a library written by Facebook that we pull into the project 1451 01:24:56,950 --> 01:25:01,576 that we're writing, just because we want the ability to use 1452 01:25:01,576 --> 01:25:04,450 all the features of React without having to write the code ourselves. 1453 01:25:04,450 --> 01:25:07,814 Imagine every time you want to write a React native application. 1454 01:25:07,814 --> 01:25:09,730 Imagine you have to write all of React native. 1455 01:25:09,730 --> 01:25:10,910 That would not be fun. 1456 01:25:10,910 --> 01:25:13,780 And, in fact, it would not be fast at all. 1457 01:25:13,780 --> 01:25:16,370 Which is the big benefit of writing in React native. 1458 01:25:16,370 --> 01:25:19,036 And so what we can do is we can actually use other people's code 1459 01:25:19,036 --> 01:25:22,200 and bring that into our own projects. 1460 01:25:22,200 --> 01:25:26,500 And so since React native is just doing JavaScript, 1461 01:25:26,500 --> 01:25:28,930 it's writing JavaScript and evaluating JavaScript, 1462 01:25:28,930 --> 01:25:33,750 you can add any JavaScript code to your project. 1463 01:25:33,750 --> 01:25:36,310 And so any library written in pure JavaScript, 1464 01:25:36,310 --> 01:25:39,040 you can just pull in and use that code in your project. 1465 01:25:39,040 --> 01:25:44,562 And so there are plenty of great tools that give you a bunch of functions 1466 01:25:44,562 --> 01:25:45,270 that you can use. 1467 01:25:45,270 --> 01:25:49,210 So like Lodash, Underscore, Ramda. 1468 01:25:49,210 --> 01:25:53,170 These are all just tool belts that give you access to functions 1469 01:25:53,170 --> 01:25:55,330 that you might use very often. 1470 01:25:55,330 --> 01:25:58,330 And you can just go ahead and pull all that JavaScript into your project 1471 01:25:58,330 --> 01:26:00,522 and use it as you see fit. 1472 01:26:00,522 --> 01:26:02,230 The way you that you install these things 1473 01:26:02,230 --> 01:26:06,880 is by using NPM, or Node Package Manager. 1474 01:26:06,880 --> 01:26:11,140 For those of you who are not familiar with package managers, 1475 01:26:11,140 --> 01:26:13,540 is it allows you to just-- 1476 01:26:13,540 --> 01:26:15,070 manages the packages for you. 1477 01:26:15,070 --> 01:26:18,730 These packages, synonymous with libraries. 1478 01:26:18,730 --> 01:26:20,860 And so you can say, rather than me having 1479 01:26:20,860 --> 01:26:24,070 to go and find where the source code of React is, 1480 01:26:24,070 --> 01:26:27,970 and download it, and then upload it into my project, 1481 01:26:27,970 --> 01:26:30,630 and then go ahead and import into my project. 1482 01:26:30,630 --> 01:26:32,590 Oh no, versions don't match. 1483 01:26:32,590 --> 01:26:36,920 That's all taken care of for you buy this thing called NPM. 1484 01:26:36,920 --> 01:26:39,430 And so if you say, hey, I want React. 1485 01:26:39,430 --> 01:26:41,350 You can just say, NPM install react. 1486 01:26:41,350 --> 01:26:44,350 It will find where React is located for you. 1487 01:26:44,350 --> 01:26:46,060 It will download it for you. 1488 01:26:46,060 --> 01:26:48,760 It will keep track of the correct version number for you. 1489 01:26:48,760 --> 01:26:52,172 And then you can just go ahead and import that into your project. 1490 01:26:52,172 --> 01:26:53,630 And how does it keep track for you? 1491 01:26:53,630 --> 01:26:56,380 Well, that's what that package.json is. 1492 01:26:56,380 --> 01:27:00,370 So every single project that we've seen before, there's this thing 1493 01:27:00,370 --> 01:27:02,440 called package.json. 1494 01:27:02,440 --> 01:27:05,320 And inside it, there are a few different key value pairs. 1495 01:27:05,320 --> 01:27:08,740 And one important one is called dependencies. 1496 01:27:08,740 --> 01:27:12,310 Dependencies, or in other word, what other code do I need in order 1497 01:27:12,310 --> 01:27:14,590 to make this application work? 1498 01:27:14,590 --> 01:27:16,390 Obviously I'm going to need React. 1499 01:27:16,390 --> 01:27:19,540 Because every single file, the first line is what? 1500 01:27:19,540 --> 01:27:21,350 Import React from React. 1501 01:27:21,350 --> 01:27:22,270 Well, where is React? 1502 01:27:22,270 --> 01:27:23,950 Well, it's right here. 1503 01:27:23,950 --> 01:27:26,770 And so what this package.json does is it says, 1504 01:27:26,770 --> 01:27:30,680 hey, this is the exact version of React that we need. 1505 01:27:30,680 --> 01:27:33,790 NPM go find that for me, go download it for me, 1506 01:27:33,790 --> 01:27:37,244 and keep track of where it is so that I can import it into my project. 1507 01:27:37,244 --> 01:27:38,410 What else do we need to run? 1508 01:27:38,410 --> 01:27:41,552 Well we need Expo and we need React native. 1509 01:27:41,552 --> 01:27:44,510 And if we need other libraries, we need to make sure that they're here. 1510 01:27:44,510 --> 01:27:47,140 So that when other people want to use our project, 1511 01:27:47,140 --> 01:27:49,060 they have those when they want to install. 1512 01:27:49,060 --> 01:27:54,857 And so many of you have probably used this command called NPM install, 1513 01:27:54,857 --> 01:27:56,440 and now you know exactly what it does. 1514 01:27:56,440 --> 01:27:58,148 Is it reads through all your dependencies 1515 01:27:58,148 --> 01:28:01,344 and goes in find them and downloads them for you. 1516 01:28:01,344 --> 01:28:04,160 1517 01:28:04,160 --> 01:28:13,430 And so now let's say in row, we want to define some prop types. 1518 01:28:13,430 --> 01:28:21,100 So we've seen before, this line, import prop types from prop types. 1519 01:28:21,100 --> 01:28:24,070 1520 01:28:24,070 --> 01:28:25,770 And then we go how do you use it. 1521 01:28:25,770 --> 01:28:29,710 We can say row dot prop types is this object where we're 1522 01:28:29,710 --> 01:28:33,290 expecting a name, which is a string. 1523 01:28:33,290 --> 01:28:36,660 And we're expecting phone, which is also a string. 1524 01:28:36,660 --> 01:28:43,910 1525 01:28:43,910 --> 01:28:47,660 So we've gone ahead and imported this thing called prop types 1526 01:28:47,660 --> 01:28:51,560 from this library called prop types. 1527 01:28:51,560 --> 01:28:53,810 But what is prop types? 1528 01:28:53,810 --> 01:28:58,290 Well this is actually going to work, believe it or not. 1529 01:28:58,290 --> 01:29:01,441 And it's a little bit strange why it works. 1530 01:29:01,441 --> 01:29:04,190 The reason that it works is because other the libraries that we're 1531 01:29:04,190 --> 01:29:06,320 importing, also import prop types. 1532 01:29:06,320 --> 01:29:09,690 And so we it just happens to be the case that prop types is already 1533 01:29:09,690 --> 01:29:11,642 installed for us. 1534 01:29:11,642 --> 01:29:14,600 But we're not guaranteed that it's already going to be installed first. 1535 01:29:14,600 --> 01:29:18,860 So what we should do is NPM install prop types. 1536 01:29:18,860 --> 01:29:21,410 Which is saying, hey, in this project, we actually 1537 01:29:21,410 --> 01:29:24,080 need this external library called prop types. 1538 01:29:24,080 --> 01:29:29,180 NPM go install it for me and then make sure to note it. 1539 01:29:29,180 --> 01:29:36,380 And so now, if you see, in our package.json file, 1540 01:29:36,380 --> 01:29:38,990 prop types was automatically added for us. 1541 01:29:38,990 --> 01:29:44,540 And so NPM is this great software that just manages all of our packages 1542 01:29:44,540 --> 01:29:45,350 for us. 1543 01:29:45,350 --> 01:29:48,710 It finds what we need, and installs it, and keeps track of version numbers. 1544 01:29:48,710 --> 01:29:53,570 And it makes sure that whoever is using my project, when they type NPM install, 1545 01:29:53,570 --> 01:29:56,352 they get the dependencies that they need to run my project. 1546 01:29:56,352 --> 01:29:59,740 1547 01:29:59,740 --> 01:30:03,790 And so if you're using an NPM version before NPM 5, 1548 01:30:03,790 --> 01:30:09,220 and so you can tell what NPM version you're using by doing NPM --version. 1549 01:30:09,220 --> 01:30:11,560 I'm running 5.6. 1550 01:30:11,560 --> 01:30:17,020 Since that is newer than NPM 5, I don't need to use this dash dash save flag. 1551 01:30:17,020 --> 01:30:21,280 Before NPM five, if you just did NPM install, 1552 01:30:21,280 --> 01:30:24,530 it wouldn't add it to your package.json, and now that's the default. 1553 01:30:24,530 --> 01:30:27,370 But if you are using an older version of NPM, 1554 01:30:27,370 --> 01:30:31,300 then you're going to have to use that dash dash save flag. 1555 01:30:31,300 --> 01:30:33,870 Or if you want to install a library globally, 1556 01:30:33,870 --> 01:30:39,610 so like we did with React tools, you're going to have to use that dash G flag. 1557 01:30:39,610 --> 01:30:42,670 And what that does is it gives you access to that library everywhere 1558 01:30:42,670 --> 01:30:44,010 on your computer. 1559 01:30:44,010 --> 01:30:45,910 And so the reason that we could just type 1560 01:30:45,910 --> 01:30:50,560 React dev tools was at the command line is because that package 1561 01:30:50,560 --> 01:30:54,964 is installed globally on our computer. 1562 01:30:54,964 --> 01:30:58,049 1563 01:30:58,049 --> 01:31:00,840 The reason it wasn't working is because there's another one running 1564 01:31:00,840 --> 01:31:03,242 on this separate window. 1565 01:31:03,242 --> 01:31:06,200 And then, lastly, all we need to do is just import into to our project. 1566 01:31:06,200 --> 01:31:09,180 And so a line that we see all the time is import React from React. 1567 01:31:09,180 --> 01:31:14,100 And what that does is it says, hey, go get that package called React, 1568 01:31:14,100 --> 01:31:19,821 import its export default or its default export into our project, name it React. 1569 01:31:19,821 --> 01:31:21,570 And now I'm free to go ahead and use that. 1570 01:31:21,570 --> 01:31:24,450 And so if I want to use any other library, all I could do 1571 01:31:24,450 --> 01:31:29,370 is NPM install that library, make sure that it's added to our package.json, 1572 01:31:29,370 --> 01:31:33,060 so other people who use our project can go ahead 1573 01:31:33,060 --> 01:31:34,410 and install that for themselves. 1574 01:31:34,410 --> 01:31:37,165 And that's done automatically by NPM. 1575 01:31:37,165 --> 01:31:39,540 And them we can go ahead and import that into our project 1576 01:31:39,540 --> 01:31:42,180 and use it as we please. 1577 01:31:42,180 --> 01:31:45,960 And so in future lectures, we'll see other JavaScript libraries 1578 01:31:45,960 --> 01:31:48,120 that we'll be using. 1579 01:31:48,120 --> 01:31:50,400 So React navigation we'll see very soon. 1580 01:31:50,400 --> 01:31:53,570 And we'll see other libraries like Redux. 1581 01:31:53,570 --> 01:31:56,940 That's just us using other people's code to our benefit. 1582 01:31:56,940 --> 01:31:59,640 We don't have to re-implement other people's projects. 1583 01:31:59,640 --> 01:32:01,210 We don't have to reinvent the wheel. 1584 01:32:01,210 --> 01:32:03,626 We can just go ahead and build upon what other people have 1585 01:32:03,626 --> 01:32:05,380 written on our own app. 1586 01:32:05,380 --> 01:32:10,062 And so a lot of non-replicated effort on our part. 1587 01:32:10,062 --> 01:32:12,270 So next week we'll go ahead and dive into navigation. 1588 01:32:12,270 --> 01:32:22,589 We'll see how, right now we're using the if the state says to show the form, 1589 01:32:22,589 --> 01:32:24,130 go ahead and render a different page. 1590 01:32:24,130 --> 01:32:26,070 Otherwise render original page. 1591 01:32:26,070 --> 01:32:29,820 Next week we'll see exactly how we're going to do that scalably. 1592 01:32:29,820 --> 01:32:33,030 Because right now, if we have 10 different pages, 1593 01:32:33,030 --> 01:32:36,140 we don't really want, if this page is visible, render this page. 1594 01:32:36,140 --> 01:32:37,890 If this page is visible, then render this. 1595 01:32:37,890 --> 01:32:41,880 We're going to see a library that allows us to better navigate our application. 1596 01:32:41,880 --> 01:32:45,720 And it will give us the ability to have things pop on top of each other, 1597 01:32:45,720 --> 01:32:48,180 go back and forth. 1598 01:32:48,180 --> 01:32:50,100 And so we'll dive into that library. 1599 01:32:50,100 --> 01:32:52,260 And so we actually have a guest lecturer. 1600 01:32:52,260 --> 01:32:56,830 The people who wrote the library itself join us next week. 1601 01:32:56,830 --> 01:32:57,450 Next lecture. 1602 01:32:57,450 --> 01:32:58,970 Next week is spring break. 1603 01:32:58,970 --> 01:33:02,620 And so we have that to look forward to in the coming lecture. 1604 01:33:02,620 --> 01:33:05,070 So thanks everyone. 1605 01:33:05,070 --> 01:33:06,859