1 00:00:00,000 --> 00:00:06,266 [MUSIC PLAYING] 2 00:00:06,266 --> 00:00:12,050 3 00:00:12,050 --> 00:00:14,518 BRIAN YU: OK, welcome back everyone to CS50 Beyond. 4 00:00:14,518 --> 00:00:16,309 We continue where we left off this morning. 5 00:00:16,309 --> 00:00:19,190 This morning we introduced React, a JavaScript-based framework 6 00:00:19,190 --> 00:00:21,170 to allow us to quickly and easily build user 7 00:00:21,170 --> 00:00:24,051 interfaces via declarative programming, describing 8 00:00:24,051 --> 00:00:26,300 what it is that we want the page to look like in terms 9 00:00:26,300 --> 00:00:27,797 of various different components. 10 00:00:27,797 --> 00:00:29,630 Then putting those components together to be 11 00:00:29,630 --> 00:00:31,400 able to create an application that's interactive. 12 00:00:31,400 --> 00:00:33,276 In order to update the application, we didn't 13 00:00:33,276 --> 00:00:35,608 need to do what we did before in the world of imperative 14 00:00:35,608 --> 00:00:37,760 programming of saying, go to this part of the page 15 00:00:37,760 --> 00:00:40,970 and insert certain components or other HTML elements 16 00:00:40,970 --> 00:00:42,560 inside this section of the page. 17 00:00:42,560 --> 00:00:45,800 We would just update our data, update the state of our components 18 00:00:45,800 --> 00:00:50,210 in order to say this value of the state should take on this new value. 19 00:00:50,210 --> 00:00:53,300 And React would take care of the process of updating the user 20 00:00:53,300 --> 00:00:56,507 interface to reflect whatever it is was contained inside of our state. 21 00:00:56,507 --> 00:00:58,340 So we're going to pick up where we left off, 22 00:00:58,340 --> 00:01:01,280 continuing in with the morning project. 23 00:01:01,280 --> 00:01:03,447 So there are a number of different ways to solve 24 00:01:03,447 --> 00:01:05,030 the problem in this morning's project. 25 00:01:05,030 --> 00:01:06,890 I'll show you a couple of them now just to give you 26 00:01:06,890 --> 00:01:08,420 a sense for the different approaches, the way 27 00:01:08,420 --> 00:01:10,970 that you can use React to implement some of these features. 28 00:01:10,970 --> 00:01:13,610 And then I'll introduce what the afternoon project will be. 29 00:01:13,610 --> 00:01:15,762 And the main focus of the afternoon lecture 30 00:01:15,762 --> 00:01:17,720 is just going to be thinking in React, thinking 31 00:01:17,720 --> 00:01:20,060 about what components we need, what state we need, 32 00:01:20,060 --> 00:01:21,710 how we might set up an application. 33 00:01:21,710 --> 00:01:25,670 And then we'll actually go ahead and try and implement the afternoon project. 34 00:01:25,670 --> 00:01:28,680 So let's go ahead and get started with the to-do list application, where 35 00:01:28,680 --> 00:01:29,960 we left it off this morning. 36 00:01:29,960 --> 00:01:33,080 So as of earlier this morning, we had a to-do list application 37 00:01:33,080 --> 00:01:36,920 that had a list of tasks, whereby I could type in a task, task one, 38 00:01:36,920 --> 00:01:38,600 and I click Add task. 39 00:01:38,600 --> 00:01:40,690 And that allows Add tasks to show up in this list. 40 00:01:40,690 --> 00:01:45,090 But of course, task one is still listed here in the input field. 41 00:01:45,090 --> 00:01:48,570 How do I get rid of task one from the input field? 42 00:01:48,570 --> 00:01:51,830 Going back to this morning, how would I remove task one from the input field 43 00:01:51,830 --> 00:01:54,350 when I click Add task, clearing out that field? 44 00:01:54,350 --> 00:02:00,897 45 00:02:00,897 --> 00:02:02,230 Which function needs the change? 46 00:02:02,230 --> 00:02:02,910 Yeah? 47 00:02:02,910 --> 00:02:05,449 AUDIENCE: Send the value of input to empty string. 48 00:02:05,449 --> 00:02:07,740 BRIAN YU: Good, set the value of input to empty string. 49 00:02:07,740 --> 00:02:10,176 And where should I do that, in which function? 50 00:02:10,176 --> 00:02:11,550 AUDIENCE: In add task? 51 00:02:11,550 --> 00:02:12,880 BRIAN YU: Great, in add task. 52 00:02:12,880 --> 00:02:15,490 So when I add a new task, I want to do two things. 53 00:02:15,490 --> 00:02:18,610 In addition to taking my tasks array and updating it, filling it 54 00:02:18,610 --> 00:02:21,400 in with the new thing, I also want to say, all right 55 00:02:21,400 --> 00:02:24,190 whatever the value of the input field was before, just 56 00:02:24,190 --> 00:02:26,980 go ahead and set that equal to the empty string, because I 57 00:02:26,980 --> 00:02:31,430 want to clear out the input field as soon as I click the Add task button. 58 00:02:31,430 --> 00:02:33,430 So I'll go ahead and refresh this, try this out. 59 00:02:33,430 --> 00:02:35,830 I type in task one, click Add task. 60 00:02:35,830 --> 00:02:39,777 And all right, great, the task shows up and this field clears itself out. 61 00:02:39,777 --> 00:02:41,860 The other thing that we ask you to do this morning 62 00:02:41,860 --> 00:02:46,200 was show a count of how many tasks are currently in the task list. 63 00:02:46,200 --> 00:02:49,277 And someone else tell me how you did that. 64 00:02:49,277 --> 00:02:51,610 What did you change and what code did you have to write? 65 00:02:51,610 --> 00:02:57,584 66 00:02:57,584 --> 00:02:58,750 I know many of you did this. 67 00:02:58,750 --> 00:02:59,890 So how did you do it? 68 00:02:59,890 --> 00:03:01,690 Show how many tasks I currently have. 69 00:03:01,690 --> 00:03:05,520 70 00:03:05,520 --> 00:03:06,090 Yeah? 71 00:03:06,090 --> 00:03:07,230 AUDIENCE: Use .length. 72 00:03:07,230 --> 00:03:09,960 BRIAN YU: Yeah, if you have an array in JavaScript, and you use .length, 73 00:03:09,960 --> 00:03:13,126 you can get at the length of the array, the number of elements in the array. 74 00:03:13,126 --> 00:03:16,350 And so if I wanted to display the number of tasks that I currently have, 75 00:03:16,350 --> 00:03:20,940 I could just say number of tasks. 76 00:03:20,940 --> 00:03:24,120 And then using curly braces, again, to mean plug-in some JavaScript value 77 00:03:24,120 --> 00:03:26,980 here, where are my tasks stored? 78 00:03:26,980 --> 00:03:29,579 What would I type? 79 00:03:29,579 --> 00:03:30,120 In the state? 80 00:03:30,120 --> 00:03:32,250 OK, this .state.tasks. 81 00:03:32,250 --> 00:03:36,990 And then .length to get at, OK, here is the number of tasks that I actually 82 00:03:36,990 --> 00:03:41,820 have as of this moment inside of my application state. 83 00:03:41,820 --> 00:03:42,890 So I refresh that. 84 00:03:42,890 --> 00:03:45,330 And now I see, OK, tasks, number of tasks is zero. 85 00:03:45,330 --> 00:03:48,420 But as soon as I add a first task here and click Add task, 86 00:03:48,420 --> 00:03:50,070 multiple things happen. 87 00:03:50,070 --> 00:03:51,520 The list updates. 88 00:03:51,520 --> 00:03:54,180 We also see that this clears out and number of tasks 89 00:03:54,180 --> 00:03:57,280 updates to reflect the length of that array. 90 00:03:57,280 --> 00:04:00,589 Questions about any of that? 91 00:04:00,589 --> 00:04:03,380 All right, so the challenging piece of this, of the morning project 92 00:04:03,380 --> 00:04:05,150 was really the deletion of tasks. 93 00:04:05,150 --> 00:04:07,040 How do you take a task in this list of tasks 94 00:04:07,040 --> 00:04:08,860 and delete it so we no longer have it? 95 00:04:08,860 --> 00:04:11,990 And so let's take a look at how we implemented that. 96 00:04:11,990 --> 00:04:13,380 We'll scroll up to the top. 97 00:04:13,380 --> 00:04:17,220 For every list item, when we map over all of our tasks, right now 98 00:04:17,220 --> 00:04:21,240 we just have a list item that lists the name of the task just like this. 99 00:04:21,240 --> 00:04:24,660 If I wanted to do more than that, well, I could just add to this list item. 100 00:04:24,660 --> 00:04:29,520 In addition to just having a task, I'll also have a button, for example. 101 00:04:29,520 --> 00:04:33,690 And that button we'll just call delete. 102 00:04:33,690 --> 00:04:36,480 And let's leave it at that for now, just putting a button there. 103 00:04:36,480 --> 00:04:37,860 Right now the button doesn't do anything. 104 00:04:37,860 --> 00:04:39,693 But let's at least see it so we can visually 105 00:04:39,693 --> 00:04:42,212 see what that button looks like on the to-do page. 106 00:04:42,212 --> 00:04:43,170 We'll refresh the page. 107 00:04:43,170 --> 00:04:44,790 OK, number of tasks is zero. 108 00:04:44,790 --> 00:04:47,752 And I could say, OK, task one for example, add the task there. 109 00:04:47,752 --> 00:04:49,710 And all right, great, we see the Delete button. 110 00:04:49,710 --> 00:04:51,931 We also see task 1 show up next to it. 111 00:04:51,931 --> 00:04:53,430 They're a little bit close together. 112 00:04:53,430 --> 00:04:55,860 So you might try and modify some of the spacing of things, 113 00:04:55,860 --> 00:04:57,961 the margin around the button, for instance, 114 00:04:57,961 --> 00:05:00,210 in order to give yourself more space if you wanted to. 115 00:05:00,210 --> 00:05:04,000 But of course right now, even if I have multiple tasks, I can click Delete 116 00:05:04,000 --> 00:05:07,470 and the delete buttons aren't doing anything just yet. 117 00:05:07,470 --> 00:05:10,020 So how do we actually delete a task? 118 00:05:10,020 --> 00:05:12,000 Well, we probably want some function that's 119 00:05:12,000 --> 00:05:14,010 going to take care of deleting a task. 120 00:05:14,010 --> 00:05:18,420 And so one way to do this might be to say, all right, delete task. 121 00:05:18,420 --> 00:05:21,062 And I saw people approach this in a couple different ways. 122 00:05:21,062 --> 00:05:22,770 So I'll show you both ways that you could 123 00:05:22,770 --> 00:05:24,610 have tried to approach this problem. 124 00:05:24,610 --> 00:05:27,180 One way would have been to say, all right, delete task. 125 00:05:27,180 --> 00:05:29,055 Well, this is a function that's going to take 126 00:05:29,055 --> 00:05:31,980 some argument, some like index for which task 127 00:05:31,980 --> 00:05:35,300 it is that I actually want to delete. 128 00:05:35,300 --> 00:05:38,690 And the logic there would be, well, all right, 129 00:05:38,690 --> 00:05:42,110 when I click on the button, button on-click. 130 00:05:42,110 --> 00:05:44,960 Let me go ahead and delete that specific task corresponding 131 00:05:44,960 --> 00:05:47,460 to index I, which is the index I'm currently on. 132 00:05:47,460 --> 00:05:50,404 So you might have tried to write something like this .deletetask. 133 00:05:50,404 --> 00:05:52,820 And then in parentheses, you might have thought all right, 134 00:05:52,820 --> 00:05:56,090 let me put in the variable I there. 135 00:05:56,090 --> 00:05:58,190 Now, this doesn't quite work. 136 00:05:58,190 --> 00:06:01,335 Does anyone know why this doesn't quite work? 137 00:06:01,335 --> 00:06:02,530 It's a little bit subtle. 138 00:06:02,530 --> 00:06:07,958 139 00:06:07,958 --> 00:06:08,458 Yeah? 140 00:06:08,458 --> 00:06:12,410 141 00:06:12,410 --> 00:06:13,090 Exactly. 142 00:06:13,090 --> 00:06:13,610 Exactly. 143 00:06:13,610 --> 00:06:17,450 This on-click attribute should take as its argument a function. 144 00:06:17,450 --> 00:06:19,370 And the idea is that that function will not 145 00:06:19,370 --> 00:06:22,880 be called upon until we actually click on the button. 146 00:06:22,880 --> 00:06:24,830 But right now what we're passing into on-click 147 00:06:24,830 --> 00:06:26,970 is the result of calling a function. 148 00:06:26,970 --> 00:06:29,210 The fact that you see parentheses after this function 149 00:06:29,210 --> 00:06:32,147 means that we're actually calling the delete task function, which 150 00:06:32,147 --> 00:06:33,230 is not what we want to do. 151 00:06:33,230 --> 00:06:35,450 What we want to do is we want to pass the function 152 00:06:35,450 --> 00:06:38,330 into the on-click attribute, but not actually call 153 00:06:38,330 --> 00:06:40,700 the function until we click on it. 154 00:06:40,700 --> 00:06:43,910 So a couple ways to potentially handle that, the simplest way might 155 00:06:43,910 --> 00:06:48,770 have been just to wrap this whole thing inside of a function, where, oops, 156 00:06:48,770 --> 00:06:51,580 undo that. 157 00:06:51,580 --> 00:06:54,300 What did I just do? 158 00:06:54,300 --> 00:06:57,780 Delete task takes an index. 159 00:06:57,780 --> 00:06:59,760 I think I accidentally deleted that. 160 00:06:59,760 --> 00:07:05,960 And instead of saying on-click equals this .deletetaskI. 161 00:07:05,960 --> 00:07:07,950 We can wrap this entire thing in a function 162 00:07:07,950 --> 00:07:11,040 as simply as adding an extra set of parentheses and an arrow. 163 00:07:11,040 --> 00:07:13,710 Remember, that arrow syntax creates a function. 164 00:07:13,710 --> 00:07:17,000 And so we've created a function that doesn't take any arguments, 165 00:07:17,000 --> 00:07:21,280 but that when it's run, will actually perform the deletion of the task. 166 00:07:21,280 --> 00:07:24,020 So this is one way to do things. 167 00:07:24,020 --> 00:07:28,130 And so now what exactly does the delete task function need to do? 168 00:07:28,130 --> 00:07:31,610 Well, it needs to remove the task at this particular index. 169 00:07:31,610 --> 00:07:34,250 So I'm going to say this .setstate. 170 00:07:34,250 --> 00:07:37,340 And the new state is going to be a function of the old state. 171 00:07:37,340 --> 00:07:41,090 I'm going to take the old state, modify it by removing the task, 172 00:07:41,090 --> 00:07:43,340 and then returning the new state. 173 00:07:43,340 --> 00:07:47,940 So this is going to be a function that takes the old state. 174 00:07:47,940 --> 00:07:50,230 And then what do we need to do? 175 00:07:50,230 --> 00:07:53,250 Well, the first thing we need to do is get a copy of that list of tasks. 176 00:07:53,250 --> 00:07:56,050 Because I can't modify the state itself, as we mentioned before, 177 00:07:56,050 --> 00:07:58,530 you should never modify the state directly and react. 178 00:07:58,530 --> 00:08:00,790 So I'm going to create a variable called Tasks. 179 00:08:00,790 --> 00:08:06,000 And that's just going to be equal to this .state.tasks filled into a brand 180 00:08:06,000 --> 00:08:07,160 new array. 181 00:08:07,160 --> 00:08:12,260 So I create a copy of that list, save it inside of a variable called tasks. 182 00:08:12,260 --> 00:08:14,566 And then I want to remove whatever is at index I. 183 00:08:14,566 --> 00:08:16,940 And so as we've decided this morning, the way we would do 184 00:08:16,940 --> 00:08:19,250 that is by saying tasks.spliceindex1. 185 00:08:19,250 --> 00:08:23,840 186 00:08:23,840 --> 00:08:27,561 In other words, saying remove whatever is at index--index. 187 00:08:27,561 --> 00:08:29,060 And how many things should I remove? 188 00:08:29,060 --> 00:08:30,620 1. 189 00:08:30,620 --> 00:08:35,120 Now, the return value of splice is going to be the array that was removed, 190 00:08:35,120 --> 00:08:38,120 that was spliced out of the tasks array. 191 00:08:38,120 --> 00:08:40,700 But tasks itself, as a variable, is going 192 00:08:40,700 --> 00:08:45,290 to be the original array with whatever we wanted to remove removed. 193 00:08:45,290 --> 00:08:47,750 So there's a slight nuance there that I saw a couple people 194 00:08:47,750 --> 00:08:48,874 struggle with a little bit. 195 00:08:48,874 --> 00:08:52,280 Just know that what splice of returns is different than what 196 00:08:52,280 --> 00:08:54,560 the actual value of the tasks variable is. 197 00:08:54,560 --> 00:08:57,110 And now that I've spliced out whatever was an index, 198 00:08:57,110 --> 00:09:01,940 I can now use this variable tasks to be the new list that has the thing 199 00:09:01,940 --> 00:09:05,107 index--index removed from it. 200 00:09:05,107 --> 00:09:06,190 And so this is a function. 201 00:09:06,190 --> 00:09:09,050 So the last thing I need to do now is return something. 202 00:09:09,050 --> 00:09:12,410 And I'm going to return, all right, what should the new tasks be? 203 00:09:12,410 --> 00:09:16,550 It should be just this variable called tasks. 204 00:09:16,550 --> 00:09:19,580 And so this is a slightly more complicated set state function. 205 00:09:19,580 --> 00:09:21,827 In particular, it's more complicated because it's 206 00:09:21,827 --> 00:09:23,660 really more of a full fledged function where 207 00:09:23,660 --> 00:09:26,540 I'm defining variables, and manipulating those variables, 208 00:09:26,540 --> 00:09:28,370 and returning some value. 209 00:09:28,370 --> 00:09:32,090 Their add task meanwhile, was a much simpler function, 210 00:09:32,090 --> 00:09:35,630 whereby I could just say I didn't need to create any new variables. 211 00:09:35,630 --> 00:09:38,570 All I needed to do was say we start with this state 212 00:09:38,570 --> 00:09:40,421 and we're just going to immediately return 213 00:09:40,421 --> 00:09:43,670 this object that represents the changes that we're going to make to the state. 214 00:09:43,670 --> 00:09:46,544 And so I'd just take a look at Add task and Delete task, 215 00:09:46,544 --> 00:09:49,710 and see if you can get an understanding for the differences between the two. 216 00:09:49,710 --> 00:09:53,540 All we need to do in Add task is add to this tasks array. 217 00:09:53,540 --> 00:09:56,450 But in Delete task, we really need a little bit of extra logic 218 00:09:56,450 --> 00:09:59,600 to copy the array, remove something from the array, 219 00:09:59,600 --> 00:10:05,080 and then return what the new object should be. 220 00:10:05,080 --> 00:10:07,560 Questions about anything so far? 221 00:10:07,560 --> 00:10:10,410 This was one way to implement things from this morning. 222 00:10:10,410 --> 00:10:11,482 Yeah? 223 00:10:11,482 --> 00:10:15,090 AUDIENCE: [INAUDIBLE] 224 00:10:15,090 --> 00:10:17,280 BRIAN YU: If you're getting an error about-- so 225 00:10:17,280 --> 00:10:22,170 I would first check to make sure that your curly braces in parentheses 226 00:10:22,170 --> 00:10:24,480 match the curly braces in parentheses that I have here. 227 00:10:24,480 --> 00:10:26,520 You might be using the keyword in a place in your code 228 00:10:26,520 --> 00:10:28,120 that you're not allowed to use it. 229 00:10:28,120 --> 00:10:29,460 But if you're still getting that error after that, 230 00:10:29,460 --> 00:10:31,251 it's probably some syntax thing that we can 231 00:10:31,251 --> 00:10:33,330 take a look during the project time. 232 00:10:33,330 --> 00:10:34,920 Yeah? 233 00:10:34,920 --> 00:10:39,630 AUDIENCE: Why wouldn't we use this .setstate for delete task? 234 00:10:39,630 --> 00:10:41,960 BRIAN YU: We are using this .setstate for delete task. 235 00:10:41,960 --> 00:10:42,459 Yeah? 236 00:10:42,459 --> 00:10:45,406 237 00:10:45,406 --> 00:10:47,750 AUDIENCE: [INAUDIBLE] 238 00:10:47,750 --> 00:10:49,854 BRIAN YU: In the Add task function-- 239 00:10:49,854 --> 00:10:51,770 so this is a little bit of a nuance of the way 240 00:10:51,770 --> 00:10:53,780 that arrow functions in JavaScript work-- 241 00:10:53,780 --> 00:10:56,780 if all we're doing in a function is taking some input 242 00:10:56,780 --> 00:10:59,510 and immediately returning its output without anything else, 243 00:10:59,510 --> 00:11:02,314 I can just say state as the input, arrow, 244 00:11:02,314 --> 00:11:04,730 and then immediately give whatever the thing I'm returning 245 00:11:04,730 --> 00:11:06,359 is, which is this JavaScript object. 246 00:11:06,359 --> 00:11:08,150 And so if that's all the function is doing, 247 00:11:08,150 --> 00:11:11,580 there's no additional logic, no loops, no variables, or anything like that, 248 00:11:11,580 --> 00:11:13,910 then you don't need to explicitly say return. 249 00:11:13,910 --> 00:11:17,100 Whereas in Delete task, the function is a little more complicated. 250 00:11:17,100 --> 00:11:17,930 I need variables. 251 00:11:17,930 --> 00:11:19,640 I need to manipulate those variables. 252 00:11:19,640 --> 00:11:23,080 And so at the end of that, I do need to explicitly say return something. 253 00:11:23,080 --> 00:11:23,580 Yeah? 254 00:11:23,580 --> 00:11:26,472 255 00:11:26,472 --> 00:11:28,400 AUDIENCE: What is .something, [INAUDIBLE].. 256 00:11:28,400 --> 00:11:32,750 257 00:11:32,750 --> 00:11:36,380 BRIAN YU: This is because I'm calling this .setstate. 258 00:11:36,380 --> 00:11:41,070 And the function that I'm passing into this .setstate is this entire thing. 259 00:11:41,070 --> 00:11:42,150 This function. 260 00:11:42,150 --> 00:11:45,170 And so this function, what it's returning ultimately 261 00:11:45,170 --> 00:11:50,230 is a new set of tasks that is going to become the new state. 262 00:11:50,230 --> 00:11:50,730 Yeah? 263 00:11:50,730 --> 00:11:52,615 264 00:11:52,615 --> 00:11:54,740 AUDIENCE: Shouldn't this be just state, not .state? 265 00:11:54,740 --> 00:11:57,810 266 00:11:57,810 --> 00:12:00,870 BRIAN YU: Oh, you're right, this should just be state, not this .state. 267 00:12:00,870 --> 00:12:01,370 Thank you. 268 00:12:01,370 --> 00:12:03,220 That's a good catch. 269 00:12:03,220 --> 00:12:05,190 Yeah? 270 00:12:05,190 --> 00:12:09,803 AUDIENCE: If you put the variable conts task outside of this .setstate, 271 00:12:09,803 --> 00:12:12,800 will that work? 272 00:12:12,800 --> 00:12:16,640 BRIAN YU: If you put conts task outside of this .setstate and you do something 273 00:12:16,640 --> 00:12:21,120 like this .state.tasks here, this will work in this example, 274 00:12:21,120 --> 00:12:24,200 but it suffers from the potential for the race conditions that we talked 275 00:12:24,200 --> 00:12:30,410 about earlier where if we're basing the new state of the old state, 276 00:12:30,410 --> 00:12:35,580 we should really be using the state input to the set state function. 277 00:12:35,580 --> 00:12:38,360 So in this example, it will work fine both ways. 278 00:12:38,360 --> 00:12:42,770 But good design habit to get into the habit of doing things this way. 279 00:12:42,770 --> 00:12:43,610 Other things? 280 00:12:43,610 --> 00:12:44,520 I think there are other questions. 281 00:12:44,520 --> 00:12:45,020 Yeah? 282 00:12:45,020 --> 00:12:49,067 AUDIENCE: I think we probably have [INAUDIBLE].. 283 00:12:49,067 --> 00:12:49,650 BRIAN YU: Yep. 284 00:12:49,650 --> 00:12:54,410 285 00:12:54,410 --> 00:12:58,820 AUDIENCE: So we decided to practice using [INAUDIBLE].. 286 00:12:58,820 --> 00:13:04,510 287 00:13:04,510 --> 00:13:07,390 BRIAN YU: Right, we're wrapping this delete task inside of a function 288 00:13:07,390 --> 00:13:11,070 so the delete task isn't run until we actually call this function. 289 00:13:11,070 --> 00:13:13,530 And this is a common way in programming to delay 290 00:13:13,530 --> 00:13:16,470 the evaluation of some expression is just to wrap the whole thing 291 00:13:16,470 --> 00:13:17,520 inside of a function. 292 00:13:17,520 --> 00:13:23,930 And only when you call that function will the value actually be evaluated. 293 00:13:23,930 --> 00:13:25,030 So this will work. 294 00:13:25,030 --> 00:13:28,300 This actually is a little bit inefficient in the sense 295 00:13:28,300 --> 00:13:31,810 that every time I generate a button, it's 296 00:13:31,810 --> 00:13:34,075 going to regenerate one of these new functions. 297 00:13:34,075 --> 00:13:36,700 And so I'll show you another way of doing the exact same thing. 298 00:13:36,700 --> 00:13:40,030 Totally fine to do this, but if you're looking for really trying to optimize 299 00:13:40,030 --> 00:13:43,430 your react code, I'll show you one other method of achieving the same goal, 300 00:13:43,430 --> 00:13:46,630 where instead of wrapping this whole thing in a function, 301 00:13:46,630 --> 00:13:50,746 I can just use this .delete task. 302 00:13:50,746 --> 00:13:52,620 Again, I'm not calling the function just yet. 303 00:13:52,620 --> 00:13:55,000 Delete task is going to be called eventually. 304 00:13:55,000 --> 00:14:00,030 But this time delete task is not going to take an index as its argument. 305 00:14:00,030 --> 00:14:02,700 But instead, what I'm going to do is I'm going to associate 306 00:14:02,700 --> 00:14:05,089 some data with this button. 307 00:14:05,089 --> 00:14:08,130 In the same way that in JavaScript before we could attach data attributes 308 00:14:08,130 --> 00:14:10,310 to HTML elements, we can do the same thing here, 309 00:14:10,310 --> 00:14:15,510 because this is just JavaScript, where I can say buttondata-index is going 310 00:14:15,510 --> 00:14:18,540 to be equal to I. Remember, data attributes 311 00:14:18,540 --> 00:14:20,490 are a way of adding information data that we 312 00:14:20,490 --> 00:14:22,500 care about to our HTML elements. 313 00:14:22,500 --> 00:14:29,340 And here I'm just adding I as the data attribute of this particular button. 314 00:14:29,340 --> 00:14:32,690 So now when someone clicks on delete task, 315 00:14:32,690 --> 00:14:36,080 this delete task is going to take an event as an argument, 316 00:14:36,080 --> 00:14:38,510 because we're going to need access to the event. 317 00:14:38,510 --> 00:14:43,250 Because if we try and get at the event.target, 318 00:14:43,250 --> 00:14:46,100 that's going to give us the button, the button that we clicked on. 319 00:14:46,100 --> 00:14:49,640 And if we access the data set for that button, the data attributes of it, 320 00:14:49,640 --> 00:14:53,420 and get at the index of that dataset, what that's going to do 321 00:14:53,420 --> 00:14:56,120 is it's going to give us access to the index of the button. 322 00:14:56,120 --> 00:14:58,850 It's going to take that button, get at its data properties, 323 00:14:58,850 --> 00:15:01,340 and get at the field called data-index. 324 00:15:01,340 --> 00:15:04,910 And that will give us access to whatever the index of this particular row 325 00:15:04,910 --> 00:15:06,330 happens to be. 326 00:15:06,330 --> 00:15:11,210 And so this will behave the same way, where I can say task one and task 2. 327 00:15:11,210 --> 00:15:15,440 And if I delete task two, all right, great, I'm left with just task one. 328 00:15:15,440 --> 00:15:18,200 And the number of tasks decreases from two to one as well, 329 00:15:18,200 --> 00:15:21,830 because React is dynamically going to update the DOM with any changes 330 00:15:21,830 --> 00:15:25,137 as a result of changing the state of my components. 331 00:15:25,137 --> 00:15:27,220 So two different ways of achieving the same thing. 332 00:15:27,220 --> 00:15:28,150 I'm just showing you both, because they're 333 00:15:28,150 --> 00:15:31,420 both the types of things that you might see in the world of programming 334 00:15:31,420 --> 00:15:33,799 in React. 335 00:15:33,799 --> 00:15:34,840 Questions about anything? 336 00:15:34,840 --> 00:15:35,470 Yeah? 337 00:15:35,470 --> 00:15:39,820 AUDIENCE: If we do it this, it's like a data attribute. 338 00:15:39,820 --> 00:15:42,262 For the index we use just value. 339 00:15:42,262 --> 00:15:43,314 Does that work for you? 340 00:15:43,314 --> 00:15:45,480 BRIAN YU: Yeah, you can use other attributes as well 341 00:15:45,480 --> 00:15:47,771 and access as attributes, and that would probably work. 342 00:15:47,771 --> 00:15:53,020 343 00:15:53,020 --> 00:15:55,445 Yep? 344 00:15:55,445 --> 00:16:02,260 AUDIENCE: [INAUDIBLE] 345 00:16:02,260 --> 00:16:04,300 BRIAN YU: So again, delete task, just to review, 346 00:16:04,300 --> 00:16:07,390 is getting the index from the data attribute of the button. 347 00:16:07,390 --> 00:16:09,060 Then updating the state. 348 00:16:09,060 --> 00:16:11,620 And to update the state, we take the original tasks, 349 00:16:11,620 --> 00:16:16,884 splice out whatever was at index I, and then return the new tasks. 350 00:16:16,884 --> 00:16:19,800 And a small bit of JavaScript shorthand, which you don't need to know, 351 00:16:19,800 --> 00:16:23,580 but might be useful sometimes, is if ever you have a situation where the key 352 00:16:23,580 --> 00:16:26,160 of a JavaScript object has the same name as the value, 353 00:16:26,160 --> 00:16:28,680 you actually don't need to say tasks:task. 354 00:16:28,680 --> 00:16:32,989 If you just say tasks, that will implicitly just mean the key in a value 355 00:16:32,989 --> 00:16:33,780 have the same name. 356 00:16:33,780 --> 00:16:36,738 And so this is just a little bit of shorthand for doing the same thing. 357 00:16:36,738 --> 00:16:40,210 But no need to worry about that if you don't want to. 358 00:16:40,210 --> 00:16:42,334 Yeah? 359 00:16:42,334 --> 00:16:46,222 AUDIENCE: Are you worried about this being inside set state? 360 00:16:46,222 --> 00:16:48,794 Is it better to be outside? 361 00:16:48,794 --> 00:16:50,710 BRIAN YU: This, it doesn't matter whether this 362 00:16:50,710 --> 00:16:53,590 is inside or outside of set state, because it's not 363 00:16:53,590 --> 00:16:55,360 dependent upon the state variable. 364 00:16:55,360 --> 00:16:57,520 So you could calculate the index wherever. 365 00:16:57,520 --> 00:16:59,620 So long as you have access to the same event, 366 00:16:59,620 --> 00:17:01,795 the data index value is always going to be the same. 367 00:17:01,795 --> 00:17:04,420 So it doesn't matter if it's inside or outside of the function. 368 00:17:04,420 --> 00:17:07,810 369 00:17:07,810 --> 00:17:08,790 Other things? 370 00:17:08,790 --> 00:17:09,435 Yeah? 371 00:17:09,435 --> 00:17:13,530 AUDIENCE: [INAUDIBLE] 372 00:17:13,530 --> 00:17:17,250 BRIAN YU: Yeah so these events you can think of as the same sorts of events we 373 00:17:17,250 --> 00:17:21,720 were dealing with in JavaScript before, where when I say button on-clicked 374 00:17:21,720 --> 00:17:28,380 equals this .addtask task for instance, then the event that is happening is 375 00:17:28,380 --> 00:17:30,120 the click event. 376 00:17:30,120 --> 00:17:33,180 And the target of the click event is the button 377 00:17:33,180 --> 00:17:35,160 that I actually use to do the clicking. 378 00:17:35,160 --> 00:17:39,990 And so the way this works in the case of delete task is that when I call this 379 00:17:39,990 --> 00:17:43,380 .delete task, it's going to be provided with the click event, 380 00:17:43,380 --> 00:17:45,160 the fact that I clicked on a button. 381 00:17:45,160 --> 00:17:48,585 And if I access event.target, that's going to give me which button 382 00:17:48,585 --> 00:17:50,840 I actually clicked on to do the deleting. 383 00:17:50,840 --> 00:17:54,480 So if I have 10 buttons, each of which has a different data-index property, 384 00:17:54,480 --> 00:17:57,840 then if I go to event.target and look at what data-index is, 385 00:17:57,840 --> 00:17:59,640 I'll know which button I clicked on and so 386 00:17:59,640 --> 00:18:03,260 I'll know which task I should remove from my list of tasks. 387 00:18:03,260 --> 00:18:05,760 Yeah? 388 00:18:05,760 --> 00:18:10,476 AUDIENCE: So [INAUDIBLE],, but basically what I did is after delete task, 389 00:18:10,476 --> 00:18:15,516 hit the button I, I used the index for I. 390 00:18:15,516 --> 00:18:22,894 And then down at the function delete task, I used [INAUDIBLE].. 391 00:18:22,894 --> 00:18:25,310 BRIAN YU: Yeah, so I showed two possible ways of doing it. 392 00:18:25,310 --> 00:18:27,851 And so one way is to do it the way that you're describing it. 393 00:18:27,851 --> 00:18:28,490 Yep. 394 00:18:28,490 --> 00:18:29,151 Yeah? 395 00:18:29,151 --> 00:18:33,390 AUDIENCE: Can you explain why the code is [INAUDIBLE].. 396 00:18:33,390 --> 00:18:36,230 397 00:18:36,230 --> 00:18:39,710 BRIAN YU: So we only need event as an input to the delete task 398 00:18:39,710 --> 00:18:44,360 function because we need to use event to access the target, namely the button 399 00:18:44,360 --> 00:18:46,850 that we clicked on, because we need the button to get 400 00:18:46,850 --> 00:18:48,920 at the data attributes of the button. 401 00:18:48,920 --> 00:18:50,882 In the first method that we used, we didn't 402 00:18:50,882 --> 00:18:52,340 need to access any data attributes. 403 00:18:52,340 --> 00:18:54,530 So it didn't actually matter to have access 404 00:18:54,530 --> 00:18:58,520 to the button that was clicked on, because delete task was already 405 00:18:58,520 --> 00:19:00,600 being provided with the index. 406 00:19:00,600 --> 00:19:02,210 So we didn't need to access the event. 407 00:19:02,210 --> 00:19:05,340 408 00:19:05,340 --> 00:19:07,350 Other things? 409 00:19:07,350 --> 00:19:08,540 Yeah? 410 00:19:08,540 --> 00:19:10,720 AUDIENCE: Why is this way more efficient? 411 00:19:10,720 --> 00:19:15,040 BRIAN YU: This way is slightly more efficient because in the other way when 412 00:19:15,040 --> 00:19:19,280 we created a new function for each of the on-clicks where we did curly braces 413 00:19:19,280 --> 00:19:24,250 arrow, this .deletetaskI, that would be a situation where every time 414 00:19:24,250 --> 00:19:28,150 it's creating a new button, it's creating a brand new function in order 415 00:19:28,150 --> 00:19:29,260 to put in on-click. 416 00:19:29,260 --> 00:19:32,527 Whereas here, I'm just using the same this .delete task function. 417 00:19:32,527 --> 00:19:34,360 And so it's just a slight efficiency benefit 418 00:19:34,360 --> 00:19:35,911 that's really not a big deal here. 419 00:19:35,911 --> 00:19:37,910 Though in larger applications, you might imagine 420 00:19:37,910 --> 00:19:40,365 it could start to become a big deal. 421 00:19:40,365 --> 00:19:42,990 In this case, it's probably fine just to avoid over optimizing. 422 00:19:42,990 --> 00:19:43,865 And either way is OK. 423 00:19:43,865 --> 00:19:47,100 424 00:19:47,100 --> 00:19:49,860 All right, so really the best way to get good at React 425 00:19:49,860 --> 00:19:52,141 is to start writing applications in React. 426 00:19:52,141 --> 00:19:53,640 And we'll do some of these together. 427 00:19:53,640 --> 00:19:56,348 And so that's what the goal of today and tomorrow is going to be. 428 00:19:56,348 --> 00:19:58,720 React is a new way of thinking about writing programs. 429 00:19:58,720 --> 00:20:01,110 It's a new way of working with programs, and thinking 430 00:20:01,110 --> 00:20:04,149 about state and applications, and how to modify the user interface. 431 00:20:04,149 --> 00:20:06,690 And so we'll go through a couple now slightly larger projects 432 00:20:06,690 --> 00:20:08,670 that will step through the beginning parts together 433 00:20:08,670 --> 00:20:11,610 to give you a sense for the types of things that you can do with React 434 00:20:11,610 --> 00:20:15,440 and how to think about designing an application in React. 435 00:20:15,440 --> 00:20:17,550 And so the application we're going to build now 436 00:20:17,550 --> 00:20:22,960 is going to be a similar analog to the quiz application we had before. 437 00:20:22,960 --> 00:20:25,100 We're to create a flash card application. 438 00:20:25,100 --> 00:20:27,300 And so the flash card application is ultimately 439 00:20:27,300 --> 00:20:28,740 going to look something like this. 440 00:20:28,740 --> 00:20:31,239 When it's done, it's going to have a couple different modes. 441 00:20:31,239 --> 00:20:32,850 It will have a card Editor. 442 00:20:32,850 --> 00:20:36,210 And a card Editor basically allows me to input terms and definitions 443 00:20:36,210 --> 00:20:37,490 into the cards. 444 00:20:37,490 --> 00:20:41,355 So maybe I want to create addition flash cards, for example, 445 00:20:41,355 --> 00:20:44,480 to help me practice for the addition game that we did earlier this morning. 446 00:20:44,480 --> 00:20:47,540 So I do a front side and a backside. 447 00:20:47,540 --> 00:20:49,740 A front and a back for the card. 448 00:20:49,740 --> 00:20:50,840 Press Add card. 449 00:20:50,840 --> 00:20:53,010 And all right, that adds to this list of cards. 450 00:20:53,010 --> 00:20:58,140 I can add other front and back and more as well. 451 00:20:58,140 --> 00:21:01,480 If I wanted to delete a card, I can delete a card too. 452 00:21:01,480 --> 00:21:05,050 And then if I want to, once I'm satisfied with editing these cards, 453 00:21:05,050 --> 00:21:07,360 I can switch to the card Viewer. 454 00:21:07,360 --> 00:21:09,672 And the card Viewer is going to show me a card. 455 00:21:09,672 --> 00:21:12,130 If I click on it, it'll flip it over so I can see the back. 456 00:21:12,130 --> 00:21:14,500 If I click on it again, it will flip back to the front. 457 00:21:14,500 --> 00:21:16,600 And I can click on New card to get me a new card. 458 00:21:16,600 --> 00:21:18,014 Get me the next card in the list. 459 00:21:18,014 --> 00:21:19,930 When I click on that, it'll flip over, show me 460 00:21:19,930 --> 00:21:22,840 the back of the card, so on and so forth. 461 00:21:22,840 --> 00:21:24,720 I can switch back to the Editor. 462 00:21:24,720 --> 00:21:26,961 I can switch back to the Viewer. 463 00:21:26,961 --> 00:21:28,960 So this is the application we're going to build. 464 00:21:28,960 --> 00:21:30,620 And it seems a little bit complicated. 465 00:21:30,620 --> 00:21:32,470 But let's try and break it down into components. 466 00:21:32,470 --> 00:21:34,511 And what's the first thing that you might notice? 467 00:21:34,511 --> 00:21:36,276 What is this interface at least remind you 468 00:21:36,276 --> 00:21:38,150 of in terms of things we may have done today? 469 00:21:38,150 --> 00:21:40,680 470 00:21:40,680 --> 00:21:42,430 Yeah, it reminds you very much, hopefully, 471 00:21:42,430 --> 00:21:46,060 of the tasks management application that we did this morning of just 472 00:21:46,060 --> 00:21:47,680 creating a to do list of tasks. 473 00:21:47,680 --> 00:21:50,030 This is effectively exactly the same thing, 474 00:21:50,030 --> 00:21:53,030 except instead of a task just having one field for the task, 475 00:21:53,030 --> 00:21:55,060 the task has a front and it has a back. 476 00:21:55,060 --> 00:21:57,160 It's two input fields instead of one. 477 00:21:57,160 --> 00:21:59,290 So this interface is probably largely going 478 00:21:59,290 --> 00:22:02,560 to resemble what it is that you did earlier this morning. 479 00:22:02,560 --> 00:22:07,030 We just now need to add a Viewer to it as well to be able to view those cards 480 00:22:07,030 --> 00:22:09,882 and flip the cards over from front to back. 481 00:22:09,882 --> 00:22:11,840 So questions about the goal-- what we're trying 482 00:22:11,840 --> 00:22:15,407 to achieve in writing this application? 483 00:22:15,407 --> 00:22:17,990 All right, let's go ahead and dive right in and actually start 484 00:22:17,990 --> 00:22:19,564 working on the application. 485 00:22:19,564 --> 00:22:21,230 So we'll go ahead and create a new file. 486 00:22:21,230 --> 00:22:24,440 We'll call it flashcards.html. 487 00:22:24,440 --> 00:22:28,140 And I'll go ahead and start with just going ahead and copying 488 00:22:28,140 --> 00:22:31,400 the to-do app just so we get the basic structure of it. 489 00:22:31,400 --> 00:22:37,160 But I'm going to completely empty out what's inside of class at, at least 490 00:22:37,160 --> 00:22:39,260 for now. 491 00:22:39,260 --> 00:22:40,882 We'll give it a title of flashcards. 492 00:22:40,882 --> 00:22:42,919 493 00:22:42,919 --> 00:22:44,960 And all right, let's actually think for a moment. 494 00:22:44,960 --> 00:22:47,520 495 00:22:47,520 --> 00:22:53,990 If I say term and definition, what are the different components 496 00:22:53,990 --> 00:22:57,530 that I might divide my application into? 497 00:22:57,530 --> 00:23:01,220 Process to different components of the application? 498 00:23:01,220 --> 00:23:05,060 There are at least two big components of the application, 499 00:23:05,060 --> 00:23:08,768 distinct parts of the application that behave differently. 500 00:23:08,768 --> 00:23:13,197 501 00:23:13,197 --> 00:23:14,280 The Viewer and the Editor. 502 00:23:14,280 --> 00:23:17,780 Great, I have this Editor right here that is a place where I can edit tasks, 503 00:23:17,780 --> 00:23:19,040 add tasks to them. 504 00:23:19,040 --> 00:23:23,420 And I also have some Viewer that lets me view all of the cards 505 00:23:23,420 --> 00:23:25,880 that I currently have inside of my flash card table. 506 00:23:25,880 --> 00:23:28,820 And so those are probably at least two different components 507 00:23:28,820 --> 00:23:30,870 that are going to behave differently. 508 00:23:30,870 --> 00:23:33,950 So one thing I might do right away is say, all right, I'm 509 00:23:33,950 --> 00:23:40,590 going to have a class called card Editor that is going to be a component. 510 00:23:40,590 --> 00:23:47,940 And for now, let's go ahead and render that just by returning a div that says 511 00:23:47,940 --> 00:23:49,620 this is the Editor. 512 00:23:49,620 --> 00:23:54,270 513 00:23:54,270 --> 00:23:56,550 So all right, I have a class called card Editor. 514 00:23:56,550 --> 00:24:00,030 And all the card Editor is going to do is say this is the Editor, at least 515 00:24:00,030 --> 00:24:02,060 for now. 516 00:24:02,060 --> 00:24:05,840 In addition to that, I probably also want 517 00:24:05,840 --> 00:24:12,660 a class called card Viewer that going to extend React.component. 518 00:24:12,660 --> 00:24:17,160 And we're going to render it by returning for now this is the Viewer. 519 00:24:17,160 --> 00:24:21,990 520 00:24:21,990 --> 00:24:26,330 So all right, we have two classes, card Editor and card Viewer. 521 00:24:26,330 --> 00:24:29,210 And right now they just say this is the Editor, this is the Viewer. 522 00:24:29,210 --> 00:24:32,720 And I can test this, make sure it works by inside of my app. 523 00:24:32,720 --> 00:24:35,840 In order to render the app, let's for now just 524 00:24:35,840 --> 00:24:41,920 return a card Editor and a card Viewer. 525 00:24:41,920 --> 00:24:44,500 526 00:24:44,500 --> 00:24:48,280 We'll load both components into the application, one on top of the other, 527 00:24:48,280 --> 00:24:49,420 just to see how this looks. 528 00:24:49,420 --> 00:24:52,160 529 00:24:52,160 --> 00:24:56,880 I'll go ahead and open up flashcards.html. 530 00:24:56,880 --> 00:24:58,650 And all right, great, this is what I see. 531 00:24:58,650 --> 00:25:01,280 I see the card Editor that just says this is the Editor. 532 00:25:01,280 --> 00:25:04,010 And I see the card Viewer that just says this is the Viewer. 533 00:25:04,010 --> 00:25:06,700 534 00:25:06,700 --> 00:25:10,630 But of course I don't want to display both the Editor and the Viewer 535 00:25:10,630 --> 00:25:11,660 at the same time. 536 00:25:11,660 --> 00:25:15,130 So let's step by step start building up this application. 537 00:25:15,130 --> 00:25:18,831 What is a piece of state that I need inside of my application? 538 00:25:18,831 --> 00:25:22,060 539 00:25:22,060 --> 00:25:22,665 Yeah? 540 00:25:22,665 --> 00:25:24,790 AUDIENCE: Whether you're on Editor or Viewer? 541 00:25:24,790 --> 00:25:26,860 BRIAN YU: Exactly, whether I'm on the Editor 542 00:25:26,860 --> 00:25:28,720 or whether I'm currently on the Viewer. 543 00:25:28,720 --> 00:25:32,200 So it's some notion of, like, what the current mode of the application is. 544 00:25:32,200 --> 00:25:35,110 And so I could implement this by saying, all right, 545 00:25:35,110 --> 00:25:39,950 let's create a constructor that takes props, super props just 546 00:25:39,950 --> 00:25:43,010 to make sure that the component gets its props correctly. 547 00:25:43,010 --> 00:25:45,470 And let's give some state to this application. 548 00:25:45,470 --> 00:25:48,604 We care about knowing whether or not we're in the-- 549 00:25:48,604 --> 00:25:50,520 so we could do this state in a number of ways. 550 00:25:50,520 --> 00:25:53,840 We could say, all right, let's add a mode property to the state 551 00:25:53,840 --> 00:25:56,821 where the mode could start out being Editor, for example. 552 00:25:56,821 --> 00:25:59,070 And then mode could be any number of different things. 553 00:25:59,070 --> 00:26:01,320 But right now there are only two different modes. 554 00:26:01,320 --> 00:26:06,204 So I'll just say Editor is true. 555 00:26:06,204 --> 00:26:08,120 We'll have a piece of the state called Editor. 556 00:26:08,120 --> 00:26:09,170 By default, it is true. 557 00:26:09,170 --> 00:26:11,090 So by default, I'll see the Editor. 558 00:26:11,090 --> 00:26:15,190 And if ever the value changes, I'll show something else. 559 00:26:15,190 --> 00:26:19,390 And so, OK, what do I do now? 560 00:26:19,390 --> 00:26:23,700 Well, inside the Render function, we'll say something like if this 561 00:26:23,700 --> 00:26:30,430 .state.editor, implicitly if this .state.editor is true, 562 00:26:30,430 --> 00:26:31,920 then what do I want to do? 563 00:26:31,920 --> 00:26:36,770 Well, I want to return a card Editor. 564 00:26:36,770 --> 00:26:39,690 565 00:26:39,690 --> 00:26:46,600 And otherwise else, I want to return a card Viewer. 566 00:26:46,600 --> 00:26:50,660 And I go ahead and delete this unnecessary return here at the bottom. 567 00:26:50,660 --> 00:26:53,370 568 00:26:53,370 --> 00:26:55,640 So here is the render code for my app. 569 00:26:55,640 --> 00:26:58,880 I'm basically checking whether this .state.editor, 570 00:26:58,880 --> 00:27:01,880 should the state of my application be showing the Editor or not showing 571 00:27:01,880 --> 00:27:02,992 the Editor? 572 00:27:02,992 --> 00:27:04,700 If I am supposed to show the Editor, then 573 00:27:04,700 --> 00:27:06,770 go ahead and return the card Editor. 574 00:27:06,770 --> 00:27:09,200 Otherwise, go ahead and return the card Viewer. 575 00:27:09,200 --> 00:27:11,940 576 00:27:11,940 --> 00:27:15,210 So if I load the page now, refresh flashcards.html, 577 00:27:15,210 --> 00:27:19,830 I just see this is the Editor and I have no way of accessing the Viewer. 578 00:27:19,830 --> 00:27:20,760 I only see the Editor. 579 00:27:20,760 --> 00:27:25,799 580 00:27:25,799 --> 00:27:26,840 Questions about anything? 581 00:27:26,840 --> 00:27:30,399 582 00:27:30,399 --> 00:27:32,440 BRIAN YU: All right, so let's take the next step. 583 00:27:32,440 --> 00:27:33,357 I can have the Editor. 584 00:27:33,357 --> 00:27:36,565 And now I want some way of flipping back and forth between Editor and Viewer, 585 00:27:36,565 --> 00:27:39,940 between Editor and Viewer, going back and forth between these two components. 586 00:27:39,940 --> 00:27:43,720 And so I probably need some way inside of my app 587 00:27:43,720 --> 00:27:46,900 to change the value of this Editor piece of state. 588 00:27:46,900 --> 00:27:51,730 I want some function that is going to change whether Editor is true or false. 589 00:27:51,730 --> 00:27:54,460 So I'll go ahead and add a new function. 590 00:27:54,460 --> 00:27:59,170 And the new function, we'll call it switch mode. 591 00:27:59,170 --> 00:28:01,420 Switch mode is going to be a function that 592 00:28:01,420 --> 00:28:04,390 takes me from Editor mode to Viewer mode, and from Viewer mode 593 00:28:04,390 --> 00:28:05,080 to Editor mode. 594 00:28:05,080 --> 00:28:07,966 595 00:28:07,966 --> 00:28:10,070 So it's going to be a function. 596 00:28:10,070 --> 00:28:13,980 In order to do that switch, I need to set the state to something. 597 00:28:13,980 --> 00:28:16,710 So I'm going to start with some starting state. 598 00:28:16,710 --> 00:28:19,700 And what is the new state? 599 00:28:19,700 --> 00:28:24,320 600 00:28:24,320 --> 00:28:31,658 What goes in here to switch the mode of my application? 601 00:28:31,658 --> 00:28:32,644 Yeah? 602 00:28:32,644 --> 00:28:34,123 AUDIENCE: [INAUDIBLE]. 603 00:28:34,123 --> 00:28:43,010 604 00:28:43,010 --> 00:28:47,244 BRIAN YU: Yes, so we have inside of this .state a notion of where we are. 605 00:28:47,244 --> 00:28:49,160 If Editor is true, we should be on the Editor. 606 00:28:49,160 --> 00:28:51,118 If Editor is false, we should be on the Viewer. 607 00:28:51,118 --> 00:28:52,370 So yes, good, we need that. 608 00:28:52,370 --> 00:28:53,552 And, yes? 609 00:28:53,552 --> 00:28:56,301 AUDIENCE: Editor, [INAUDIBLE]. 610 00:28:56,301 --> 00:28:57,300 BRIAN YU: Yeah, exactly. 611 00:28:57,300 --> 00:28:59,341 Editor, we're going to change the value of Editor 612 00:28:59,341 --> 00:29:05,220 to exclamation point for not state.editor. 613 00:29:05,220 --> 00:29:08,190 So whatever the value of state.editor was before, 614 00:29:08,190 --> 00:29:11,730 let's take whatever is not that, so if it was true, it's now false. 615 00:29:11,730 --> 00:29:14,280 It was false, it will now be true. 616 00:29:14,280 --> 00:29:16,920 And that will be the new value of Editor, for example. 617 00:29:16,920 --> 00:29:22,260 618 00:29:22,260 --> 00:29:28,050 So all right, now what I need is I would like some way for maybe the Editor 619 00:29:28,050 --> 00:29:31,200 to have a button and the Viewer to have a button that 620 00:29:31,200 --> 00:29:35,140 will result in switching the mode of the application, for example. 621 00:29:35,140 --> 00:29:37,752 And so how do I go about doing that? 622 00:29:37,752 --> 00:29:39,210 Well, there are a of ways to do it. 623 00:29:39,210 --> 00:29:41,550 I could put the button directly in the app right 624 00:29:41,550 --> 00:29:43,180 here and just have a button at the bottom that's going 625 00:29:43,180 --> 00:29:44,940 to say, like, switch mode or something. 626 00:29:44,940 --> 00:29:48,960 Another way to do it would be inside of card Editor for instance, 627 00:29:48,960 --> 00:29:52,440 let's go ahead and add maybe a horizontal row. 628 00:29:52,440 --> 00:29:57,450 HR just creates a horizontal row, a line, across the page effectively, 629 00:29:57,450 --> 00:30:03,920 and a button that says go to Viewer. 630 00:30:03,920 --> 00:30:09,050 And in the Viewer, go ahead and create a horizontal row and a button that says 631 00:30:09,050 --> 00:30:09,980 go to Editor. 632 00:30:09,980 --> 00:30:14,660 633 00:30:14,660 --> 00:30:19,600 So OK, I have the task Editor that has a button that says go to the task Viewer. 634 00:30:19,600 --> 00:30:23,170 And I have the Viewer that has a button that says go to the Editor. 635 00:30:23,170 --> 00:30:25,720 If I refresh the page, it says this is the Editor 636 00:30:25,720 --> 00:30:27,940 and there's a button that says go to Viewer. 637 00:30:27,940 --> 00:30:31,950 Of course if I click on that, nothing happens. 638 00:30:31,950 --> 00:30:34,350 Nothing happens because I haven't specified 639 00:30:34,350 --> 00:30:38,130 what should happen when I click on this Go to Viewer button. 640 00:30:38,130 --> 00:30:42,240 What I would like to happen, if I click on the Go to Viewer button in the card 641 00:30:42,240 --> 00:30:51,750 Editor component, is that it calls the switch mode method of my app component. 642 00:30:51,750 --> 00:30:53,976 But there is a slight problem, what's the problem? 643 00:30:53,976 --> 00:30:55,350 Why can't I just say switch mode? 644 00:30:55,350 --> 00:30:59,000 645 00:30:59,000 --> 00:30:59,620 Yeah? 646 00:30:59,620 --> 00:31:00,880 AUDIENCE: They're in different classes. 647 00:31:00,880 --> 00:31:01,910 BRIAN YU: They're in different classes. 648 00:31:01,910 --> 00:31:02,630 Exactly. 649 00:31:02,630 --> 00:31:07,970 Switch mode is a method inside of the app component, 650 00:31:07,970 --> 00:31:12,689 but I want to be able to call it from the card Editor component. 651 00:31:12,689 --> 00:31:14,480 They're in different components, but I want 652 00:31:14,480 --> 00:31:18,630 the card Editor to still be able to call a function inside of the app. 653 00:31:18,630 --> 00:31:19,620 So how would I do that? 654 00:31:19,620 --> 00:31:21,578 Any thoughts on how I might solve that problem? 655 00:31:21,578 --> 00:31:25,550 656 00:31:25,550 --> 00:31:27,770 The function is inside of the app and I would 657 00:31:27,770 --> 00:31:29,499 like to give it to the card Editor. 658 00:31:29,499 --> 00:31:32,540 In other words, pass information about that function or pass the function 659 00:31:32,540 --> 00:31:35,640 itself to the card Editor so the card Editor can use it. 660 00:31:35,640 --> 00:31:38,310 661 00:31:38,310 --> 00:31:40,466 Thoughts on how to solve that problem? 662 00:31:40,466 --> 00:31:41,840 We saw the solution this morning. 663 00:31:41,840 --> 00:31:42,440 Yeah? 664 00:31:42,440 --> 00:31:45,590 AUDIENCE: Could you have it extend the app? 665 00:31:45,590 --> 00:31:47,600 BRIAN YU: Could you have it extend the app? 666 00:31:47,600 --> 00:31:49,400 Yes, you could. 667 00:31:49,400 --> 00:31:54,710 Generally, React doesn't recommend that you have different classes extending 668 00:31:54,710 --> 00:31:57,860 other classes, because generally the classes want 669 00:31:57,860 --> 00:31:59,150 to do pretty distinct things. 670 00:31:59,150 --> 00:32:01,810 But that could be one solution to the problem. 671 00:32:01,810 --> 00:32:02,310 Yeah? 672 00:32:02,310 --> 00:32:03,590 AUDIENCE: You can use a property. 673 00:32:03,590 --> 00:32:04,350 BRIAN YU: You can use a prop. 674 00:32:04,350 --> 00:32:04,610 Great. 675 00:32:04,610 --> 00:32:06,901 And that's going to be the solution we're going to use. 676 00:32:06,901 --> 00:32:10,400 We learned already that if I want to pass information into the card Editor, 677 00:32:10,400 --> 00:32:12,230 I can add props to the card Editor. 678 00:32:12,230 --> 00:32:20,120 I can say, all right, give the card Editor a switch mode property that is 679 00:32:20,120 --> 00:32:25,260 equal to this .switchmode. 680 00:32:25,260 --> 00:32:28,520 Remember, I'm inside of the app component right now. 681 00:32:28,520 --> 00:32:31,190 And when I load my card Editor component, 682 00:32:31,190 --> 00:32:34,880 I would like to provide it with a property called switch mode. 683 00:32:34,880 --> 00:32:38,630 And that is equal to the this .switchmode function. 684 00:32:38,630 --> 00:32:42,470 I'm passing this function into the card Editor component 685 00:32:42,470 --> 00:32:45,200 so that the card Editor component can use that function. 686 00:32:45,200 --> 00:32:48,544 687 00:32:48,544 --> 00:32:51,210 It can be helpful here to think about the hierarchical structure 688 00:32:51,210 --> 00:32:52,001 of the application. 689 00:32:52,001 --> 00:32:54,870 We have the app, which is the big container, inside of which 690 00:32:54,870 --> 00:32:56,370 is the card Editor. 691 00:32:56,370 --> 00:33:01,320 And the app is going to give the card Editor this, this.switchmode function 692 00:33:01,320 --> 00:33:06,390 so that the card Editor can now use that function. 693 00:33:06,390 --> 00:33:07,210 Yeah? 694 00:33:07,210 --> 00:33:14,770 AUDIENCE: Let's say you have a function that every single last [INAUDIBLE] 695 00:33:14,770 --> 00:33:16,846 would use. 696 00:33:16,846 --> 00:33:21,266 If you could find that function, [INAUDIBLE].. 697 00:33:21,266 --> 00:33:23,140 BRIAN YU: That's a good question about if you 698 00:33:23,140 --> 00:33:26,680 had a lot of components that were all trying to take advantage of functions 699 00:33:26,680 --> 00:33:30,536 that are modifying the state, with just React, 700 00:33:30,536 --> 00:33:32,410 you'd have to do something along these lines. 701 00:33:32,410 --> 00:33:33,520 Although, there are other libraries. 702 00:33:33,520 --> 00:33:36,280 In particularly, a library called Redux, which is quite popular, 703 00:33:36,280 --> 00:33:40,720 which helped to make that process easier and can have some useful abstractions 704 00:33:40,720 --> 00:33:42,130 for simplifying that process. 705 00:33:42,130 --> 00:33:43,720 We're not going to get our chance to talk about it this week. 706 00:33:43,720 --> 00:33:45,678 It's a little beyond on the scope of the class. 707 00:33:45,678 --> 00:33:48,340 But Redux is what you should look into if that's something 708 00:33:48,340 --> 00:33:49,381 that you're trying to do. 709 00:33:49,381 --> 00:33:51,922 710 00:33:51,922 --> 00:33:56,080 So OK, I provided the switch mode property into the card Editor. 711 00:33:56,080 --> 00:34:01,950 And now inside of card Editor, what should button on-click do? 712 00:34:01,950 --> 00:34:05,576 What is the function that I need to call when the button is clicked? 713 00:34:05,576 --> 00:34:07,770 AUDIENCE: This .prop. 714 00:34:07,770 --> 00:34:09,159 BRIAN YU: This .props.switchmode. 715 00:34:09,159 --> 00:34:12,350 716 00:34:12,350 --> 00:34:12,949 Great. 717 00:34:12,949 --> 00:34:15,469 I want to access the switch mode function, 718 00:34:15,469 --> 00:34:17,389 and the switch mode function was provided 719 00:34:17,389 --> 00:34:21,500 as one of the props of this card Viewer component. 720 00:34:21,500 --> 00:34:28,112 So when I click on the button, it should call this .props.switchmode. 721 00:34:28,112 --> 00:34:29,570 I'll go ahead and refresh the page. 722 00:34:29,570 --> 00:34:31,310 It says this is the Editor. 723 00:34:31,310 --> 00:34:34,969 I click on and go to the Viewer, and, uh-oh, something went wrong. 724 00:34:34,969 --> 00:34:38,270 725 00:34:38,270 --> 00:34:39,860 Why did that not work? 726 00:34:39,860 --> 00:34:42,740 This .props.switchmode. 727 00:34:42,740 --> 00:34:45,533 AUDIENCE: [INAUDIBLE] 728 00:34:45,533 --> 00:34:46,699 BRIAN YU: What did I not do? 729 00:34:46,699 --> 00:34:50,449 730 00:34:50,449 --> 00:34:52,429 I didn't edit-- oh, I edited the Viewer class. 731 00:34:52,429 --> 00:34:54,679 Yes, thank you. 732 00:34:54,679 --> 00:34:59,250 I'll go ahead and make the same change to the Editor class button. 733 00:34:59,250 --> 00:35:03,860 When you click on it, unclick this .props.switchmode. 734 00:35:03,860 --> 00:35:06,750 Thank you for that. 735 00:35:06,750 --> 00:35:10,220 OK, now if I refresh the page it says this is the Editor. 736 00:35:10,220 --> 00:35:12,530 If I click on Go to Viewer, it switches. 737 00:35:12,530 --> 00:35:15,830 Now I'm on the Viewer, I click go to Editor 738 00:35:15,830 --> 00:35:20,340 and why did that one not work now? 739 00:35:20,340 --> 00:35:21,620 Oh, why did that one not work? 740 00:35:21,620 --> 00:35:23,460 Why did card Viewer not work? 741 00:35:23,460 --> 00:35:24,413 Anyone know? 742 00:35:24,413 --> 00:35:25,568 AUDIENCE: [INAUDIBLE]. 743 00:35:25,568 --> 00:35:28,340 744 00:35:28,340 --> 00:35:29,990 BRIAN YU: It has this .prop.switchmode. 745 00:35:29,990 --> 00:35:31,246 But what did I forget? 746 00:35:31,246 --> 00:35:32,180 AUDIENCE: [INAUDIBLE]. 747 00:35:32,180 --> 00:35:33,140 BRIAN YU: I need to give it the prop. 748 00:35:33,140 --> 00:35:33,950 Exactly. 749 00:35:33,950 --> 00:35:37,610 So I have card Viewer, but I didn't provide it with a switch mode prop. 750 00:35:37,610 --> 00:35:42,740 And so I need to say card Viewer and switch mode prop is going to be equal 751 00:35:42,740 --> 00:35:49,250 to this .switchmode for example. 752 00:35:49,250 --> 00:35:50,530 So now I have the Editor. 753 00:35:50,530 --> 00:35:53,950 I can switch to the Viewer and hopefully I can switch back to the Editor. 754 00:35:53,950 --> 00:35:56,740 You can go back and forth between the two just 755 00:35:56,740 --> 00:36:01,310 by changing the state of the application. 756 00:36:01,310 --> 00:36:03,620 Questions about anything so far? 757 00:36:03,620 --> 00:36:08,510 758 00:36:08,510 --> 00:36:11,270 All right, so let's go ahead and try and build out this Editor. 759 00:36:11,270 --> 00:36:12,945 We'll try and build the Editor together. 760 00:36:12,945 --> 00:36:14,820 And then I'll leave most of the Viewer to you 761 00:36:14,820 --> 00:36:17,730 to try and figure out if you'd like to. 762 00:36:17,730 --> 00:36:23,380 So inside of our application, we currently 763 00:36:23,380 --> 00:36:26,620 have some state that indicates whether we're on the Editor mode 764 00:36:26,620 --> 00:36:27,850 or on the Viewer mode. 765 00:36:27,850 --> 00:36:30,670 We're also going to need some state about, like, 766 00:36:30,670 --> 00:36:34,050 what the current cards inside of my collection of flash are. 767 00:36:34,050 --> 00:36:37,480 Like, what are the cards, what's on the front, what's on the back of them. 768 00:36:37,480 --> 00:36:41,800 And an interesting question comes about of where should that state live, 769 00:36:41,800 --> 00:36:47,290 should that state be inside of app, should it be inside of card Viewer, 770 00:36:47,290 --> 00:36:50,170 or should it be inside of card Editor? 771 00:36:50,170 --> 00:36:55,532 Each is a component, each can have its own state, which component should 772 00:36:55,532 --> 00:36:57,115 maintain the list of all of the cards? 773 00:36:57,115 --> 00:37:02,042 774 00:37:02,042 --> 00:37:02,750 What do we think? 775 00:37:02,750 --> 00:37:05,400 776 00:37:05,400 --> 00:37:07,526 Yeah? 777 00:37:07,526 --> 00:37:09,700 AUDIENCE: [INAUDIBLE] Editor. 778 00:37:09,700 --> 00:37:10,700 BRIAN YU: Yeah, exactly. 779 00:37:10,700 --> 00:37:14,690 We want the state about all the cards to be accessible to both 780 00:37:14,690 --> 00:37:16,490 the Editor and the Viewer. 781 00:37:16,490 --> 00:37:18,590 So it probably makes sense to put the state 782 00:37:18,590 --> 00:37:21,680 about what all the cards are inside of the app, 783 00:37:21,680 --> 00:37:26,520 give the state access to cards, which by default will just be an empty list. 784 00:37:26,520 --> 00:37:30,440 That way we can provide that information to both the Editor and the Viewer, 785 00:37:30,440 --> 00:37:33,916 and both can have access to that same state. 786 00:37:33,916 --> 00:37:37,647 And this is an idea you'll commonly see in React called Lifting State Up 787 00:37:37,647 --> 00:37:40,230 that you might think, OK, the card Editor needs to have access 788 00:37:40,230 --> 00:37:41,790 to state about all of the cards. 789 00:37:41,790 --> 00:37:45,870 But if we lift the state up out of the card Editor and into the application, 790 00:37:45,870 --> 00:37:48,840 then anything the application uses, any of its components 791 00:37:48,840 --> 00:37:50,820 can have access to that same piece of state. 792 00:37:50,820 --> 00:37:54,450 793 00:37:54,450 --> 00:37:55,340 Questions about that? 794 00:37:55,340 --> 00:37:58,090 795 00:37:58,090 --> 00:38:02,190 All right, let's go ahead and try and build the card Editor now. 796 00:38:02,190 --> 00:38:06,090 So importantly, when I have the card Editor, 797 00:38:06,090 --> 00:38:09,540 the card Editor needs to know what the cards are. 798 00:38:09,540 --> 00:38:11,880 So I'm going to go ahead and provide the card Editor 799 00:38:11,880 --> 00:38:13,740 with an additional property. 800 00:38:13,740 --> 00:38:18,990 And that property is just going to be called cards, I suppose. 801 00:38:18,990 --> 00:38:22,200 And cards should be equal to what value? 802 00:38:22,200 --> 00:38:26,152 803 00:38:26,152 --> 00:38:27,634 AUDIENCE: This .state.cards. 804 00:38:27,634 --> 00:38:28,800 BRIAN YU: This .state.cards. 805 00:38:28,800 --> 00:38:29,299 Great. 806 00:38:29,299 --> 00:38:32,440 This is inside of my app component, and so when I have the card Editor, 807 00:38:32,440 --> 00:38:38,029 I want to provide it with cards, and its value should be this .state.cards. 808 00:38:38,029 --> 00:38:40,570 You'll notice this line is starting to get a little bit long. 809 00:38:40,570 --> 00:38:43,870 So it's often common in React paradigms to see each 810 00:38:43,870 --> 00:38:46,560 prop to be on a new line of its own. 811 00:38:46,560 --> 00:38:49,850 And so you'll often see something that looks a little something like this, 812 00:38:49,850 --> 00:38:51,580 where I'll return card Editor. 813 00:38:51,580 --> 00:38:54,030 Cards is equal to this .state.cards. 814 00:38:54,030 --> 00:38:56,530 And I'll also give it access to switch mode. 815 00:38:56,530 --> 00:39:00,180 And I'll do the same for card Viewer, give it access to cards in this 816 00:39:00,180 --> 00:39:05,910 .state.cards, give it access to switch mode for the card Viewer. 817 00:39:05,910 --> 00:39:08,250 They both need access to that same information. 818 00:39:08,250 --> 00:39:11,070 819 00:39:11,070 --> 00:39:16,860 So now let's go ahead and build our card Editor. 820 00:39:16,860 --> 00:39:19,950 Right now all it does is just say this is the Editor. 821 00:39:19,950 --> 00:39:21,310 Let's add some HTML to it. 822 00:39:21,310 --> 00:39:24,450 At this point, I can just write HTML and declaratively describe 823 00:39:24,450 --> 00:39:26,820 what it is that I want the Editor to look like. 824 00:39:26,820 --> 00:39:33,270 Well, it should be in H2, maybe, that says card Editor. 825 00:39:33,270 --> 00:39:37,020 You can make it in H1 also, make it a little bit smaller. 826 00:39:37,020 --> 00:39:40,680 And underneath the card Editor, I want there to be a table. 827 00:39:40,680 --> 00:39:43,380 A table where I have rows and columns, a way 828 00:39:43,380 --> 00:39:45,930 to show the front and the back of each card, 829 00:39:45,930 --> 00:39:48,912 and then a button to delete each card. 830 00:39:48,912 --> 00:39:50,370 So underneath this, I'll say table. 831 00:39:50,370 --> 00:39:53,010 832 00:39:53,010 --> 00:40:00,540 The table is going to have a table head and a table body, 833 00:40:00,540 --> 00:40:03,930 either just HTML just to make it easy to separate the heading of the table 834 00:40:03,930 --> 00:40:05,880 from the body of the table. 835 00:40:05,880 --> 00:40:10,200 And the heading of the table is going to have a table row, just 836 00:40:10,200 --> 00:40:12,330 a row along the top of the table. 837 00:40:12,330 --> 00:40:15,220 And that row is going to have three columns. 838 00:40:15,220 --> 00:40:19,710 The first column will be, OK, this is the front of the card, 839 00:40:19,710 --> 00:40:23,460 this is the back of the card, and here's a button 840 00:40:23,460 --> 00:40:27,020 to delete this particular card. 841 00:40:27,020 --> 00:40:31,000 So I have a row at the top of the table, front, back, delete. 842 00:40:31,000 --> 00:40:34,600 And inside the body of the table, here is now where all of the rows 843 00:40:34,600 --> 00:40:35,530 are going to go. 844 00:40:35,530 --> 00:40:39,320 And oftentimes an easy way of just doing this is by declaring a variable 845 00:40:39,320 --> 00:40:41,320 and then we can go back and actually declare it. 846 00:40:41,320 --> 00:40:45,730 I'll just say curly braces rows, meaning the rows of the table 847 00:40:45,730 --> 00:40:48,140 are going to go here. 848 00:40:48,140 --> 00:40:52,860 Now, rows is a variable I haven't yet actually defined. 849 00:40:52,860 --> 00:40:58,410 And so I can define a variable up at the top of the render function. 850 00:40:58,410 --> 00:41:01,670 I can define a variable called rows, which 851 00:41:01,670 --> 00:41:06,102 is going to be equal to, all right, well how am I going to get all the rows? 852 00:41:06,102 --> 00:41:08,060 Well, this is going to look very similar to how 853 00:41:08,060 --> 00:41:11,570 we got that unordered list of items inside of our task list. 854 00:41:11,570 --> 00:41:14,840 What I'm going to say is, where are the cards stored, 855 00:41:14,840 --> 00:41:18,780 this .state or this .props? 856 00:41:18,780 --> 00:41:19,350 Props. 857 00:41:19,350 --> 00:41:19,610 Great. 858 00:41:19,610 --> 00:41:20,109 Why props? 859 00:41:20,109 --> 00:41:25,519 860 00:41:25,519 --> 00:41:26,810 Why are the cards in the props? 861 00:41:26,810 --> 00:41:32,710 862 00:41:32,710 --> 00:41:33,382 Yeah? 863 00:41:33,382 --> 00:41:35,230 AUDIENCE: [INAUDIBLE]. 864 00:41:35,230 --> 00:41:38,800 BRIAN YU: Yeah, so in app when we were creating the card Editor, 865 00:41:38,800 --> 00:41:42,160 we passed in cards as one of the properties of the card Editor. 866 00:41:42,160 --> 00:41:47,470 And so now in order to access those cards, we can say this .props.cards. 867 00:41:47,470 --> 00:41:50,260 And then I want to again map over each of these cards, 868 00:41:50,260 --> 00:41:52,330 doing something with each card, in particular, 869 00:41:52,330 --> 00:41:54,940 creating a table row for each one of them. 870 00:41:54,940 --> 00:41:58,930 So I'll say map and we'll go map over every card, 871 00:41:58,930 --> 00:42:02,740 and also give it an index variable I so we have access to which card 872 00:42:02,740 --> 00:42:04,390 it actually is. 873 00:42:04,390 --> 00:42:09,810 And we're going to go ahead and return a table row. 874 00:42:09,810 --> 00:42:13,800 Each card is going to correspond to a single table row. 875 00:42:13,800 --> 00:42:15,810 We'll give that table row a key, because React 876 00:42:15,810 --> 00:42:20,550 likes to have anything that's iterated over a key that is unique. 877 00:42:20,550 --> 00:42:23,790 And we'll give it three cells inside of that row, a front, a back, 878 00:42:23,790 --> 00:42:25,980 and a Delete button. 879 00:42:25,980 --> 00:42:30,160 For the first cell, we'll say card.front. 880 00:42:30,160 --> 00:42:31,410 We'll make each one an object. 881 00:42:31,410 --> 00:42:34,076 Right now we haven't actually seen how we create a new card yet, 882 00:42:34,076 --> 00:42:36,750 but this is how we would print them out for instance. 883 00:42:36,750 --> 00:42:40,470 Then we'll have another one that says card.back. 884 00:42:40,470 --> 00:42:43,590 And then we'll have another one that's just a button that says delete. 885 00:42:43,590 --> 00:42:48,220 886 00:42:48,220 --> 00:42:54,170 So OK, I've defined rows, which is going to be taking all of the cards 887 00:42:54,170 --> 00:42:56,960 and mapping over them, looping over all of the cards. 888 00:42:56,960 --> 00:42:59,570 And for each card, creating a new row. 889 00:42:59,570 --> 00:43:03,710 That row has three columns, one column to represent the front of the card, one 890 00:43:03,710 --> 00:43:05,930 column to represent the back of the card, 891 00:43:05,930 --> 00:43:10,250 and one column to be a button that I can click on to delete the card. 892 00:43:10,250 --> 00:43:12,200 Very similar again to the task management 893 00:43:12,200 --> 00:43:14,000 example from earlier this morning. 894 00:43:14,000 --> 00:43:16,940 So hopefully you can see the parallels that are there as well. 895 00:43:16,940 --> 00:43:19,970 Take a look at the example from this morning at the map 896 00:43:19,970 --> 00:43:21,720 that we were doing over the list of tasks. 897 00:43:21,720 --> 00:43:24,280 And you'll see a lot of similar code that's being used here, 898 00:43:24,280 --> 00:43:27,740 a lot of similar ideas in React. 899 00:43:27,740 --> 00:43:31,640 To test this out, rather than starting cards off with an empty thing, 900 00:43:31,640 --> 00:43:37,520 I can just for the sake of example give it, OK, front is going to be test front 901 00:43:37,520 --> 00:43:40,070 and back is going to be test back. 902 00:43:40,070 --> 00:43:44,960 And we'll go ahead and add a second one, front equals test 2 front, 903 00:43:44,960 --> 00:43:47,450 back is test 2 back. 904 00:43:47,450 --> 00:43:50,330 Just giving it some default state that I'll delete eventually, 905 00:43:50,330 --> 00:43:52,580 but that'll be useful for now until I have the ability 906 00:43:52,580 --> 00:43:55,550 to add cards to be able to see what are the cards 907 00:43:55,550 --> 00:43:59,390 that I currently have inside of my application. 908 00:43:59,390 --> 00:44:03,170 If we open up flashcards.html, all right, great, 909 00:44:03,170 --> 00:44:05,780 we see now that we have a card Editor and we have 910 00:44:05,780 --> 00:44:07,810 three columns, front, back, and delete. 911 00:44:07,810 --> 00:44:09,560 The Delete button doesn't do anything yet. 912 00:44:09,560 --> 00:44:14,620 But at least now I can see the contents of my Editor. 913 00:44:14,620 --> 00:44:17,620 What questions do you have so far with what we've done just now? 914 00:44:17,620 --> 00:44:20,841 We just created an Editor where we can see the contents of whatever 915 00:44:20,841 --> 00:44:22,090 flash cards we currently have. 916 00:44:22,090 --> 00:44:24,670 917 00:44:24,670 --> 00:44:28,240 I'm going to add some CSS code just to make this look a little bit nicer. 918 00:44:28,240 --> 00:44:33,240 If we go up to the top of our HTML page, this is very similar to CSS code 919 00:44:33,240 --> 00:44:33,990 I've added before. 920 00:44:33,990 --> 00:44:35,823 So we'll go through it a little bit quickly. 921 00:44:35,823 --> 00:44:39,090 But feel free to stop and I'll post this code once we move into project time 922 00:44:39,090 --> 00:44:40,860 if you want to take a closer look at it. 923 00:44:40,860 --> 00:44:45,517 But basically tables, and table data cells, and table heading cells, 924 00:44:45,517 --> 00:44:47,850 I should probably change the headings to table headings. 925 00:44:47,850 --> 00:44:50,800 I'll actually do that now. 926 00:44:50,800 --> 00:44:54,836 The headings should probably be th instead of td. 927 00:44:54,836 --> 00:44:56,710 Effectively, this isn't changing a whole lot. 928 00:44:56,710 --> 00:44:59,561 But it helps to make sure that HTML knows that these 929 00:44:59,561 --> 00:45:01,060 are in fact headings for the tables. 930 00:45:01,060 --> 00:45:04,640 931 00:45:04,640 --> 00:45:07,200 So the table, table data cells, and table headings, 932 00:45:07,200 --> 00:45:12,510 those will have a border that is a one pixel solid block border for example. 933 00:45:12,510 --> 00:45:14,850 And so, OK, what does that look like? 934 00:45:14,850 --> 00:45:18,280 All right, we have a one pixel solid black border around each of the cells. 935 00:45:18,280 --> 00:45:21,910 I don't like the fact that there is two lines between a lot of the information. 936 00:45:21,910 --> 00:45:25,120 And so in order to collapse that inside of table, 937 00:45:25,120 --> 00:45:31,200 we can use the border collapse is collapsed CSS property. 938 00:45:31,200 --> 00:45:34,360 That'll basically take all of the neighboring sections of the border 939 00:45:34,360 --> 00:45:36,520 and just collapse them down. 940 00:45:36,520 --> 00:45:38,560 And now this feels a little bit cramped. 941 00:45:38,560 --> 00:45:40,540 So I'd like to add a little bit more space 942 00:45:40,540 --> 00:45:42,580 in between these various different elements. 943 00:45:42,580 --> 00:45:44,950 So for table data cells and table headings cells, 944 00:45:44,950 --> 00:45:49,990 let me add 10 pixels of padding on the inside of each of those cells. 945 00:45:49,990 --> 00:45:52,524 And that will be space on the interior of the border such 946 00:45:52,524 --> 00:45:55,690 that when I refresh the page now, all right, this looks a little bit better, 947 00:45:55,690 --> 00:45:57,430 at least a little more aesthetically pleasing. 948 00:45:57,430 --> 00:45:59,550 And you should feel welcome to mess with the CSS all you want. 949 00:45:59,550 --> 00:46:02,200 You can add colors, change the border if you would like to. 950 00:46:02,200 --> 00:46:04,510 You can center the table if that looks better for you. 951 00:46:04,510 --> 00:46:07,720 So feel free to make any changes to the style and the aesthetics of the code, 952 00:46:07,720 --> 00:46:12,440 and also the functionality of the code if you choose to do so. 953 00:46:12,440 --> 00:46:14,080 Questions about anything thus far? 954 00:46:14,080 --> 00:46:17,880 955 00:46:17,880 --> 00:46:21,170 All right, so we have this table. 956 00:46:21,170 --> 00:46:23,560 And now in addition to having a table, I also 957 00:46:23,560 --> 00:46:26,080 need some way of adding a new card. 958 00:46:26,080 --> 00:46:29,260 So I'll go ahead and say line break here. 959 00:46:29,260 --> 00:46:33,380 And I'll have an input whose name is going to be front 960 00:46:33,380 --> 00:46:37,440 and that'll be it for now. 961 00:46:37,440 --> 00:46:40,902 And an input whose name is going to be back, 962 00:46:40,902 --> 00:46:43,360 and actually I'll give each of them a placeholder at least. 963 00:46:43,360 --> 00:46:49,820 I'll call it front of card and place holder back of card. 964 00:46:49,820 --> 00:46:52,550 So we have two input fields now. 965 00:46:52,550 --> 00:46:55,160 And I'll have a button that says Add card. 966 00:46:55,160 --> 00:46:58,000 967 00:46:58,000 --> 00:47:01,180 So I have two input fields, one called front, one card called back. 968 00:47:01,180 --> 00:47:06,600 And a button that's going to add a new card to this list of cards. 969 00:47:06,600 --> 00:47:08,570 Press Refresh. 970 00:47:08,570 --> 00:47:11,014 Some error somewhere. 971 00:47:11,014 --> 00:47:13,740 I executed closing tag for input. 972 00:47:13,740 --> 00:47:17,040 Oh, I need a flash to close these input tags. 973 00:47:17,040 --> 00:47:21,230 974 00:47:21,230 --> 00:47:22,940 All right, now I have a card Editor. 975 00:47:22,940 --> 00:47:23,649 It's got a table. 976 00:47:23,649 --> 00:47:26,898 And I also have a place where I can type in the name of the front of the card, 977 00:47:26,898 --> 00:47:28,820 then whatever goes on the back of the card. 978 00:47:28,820 --> 00:47:33,950 And then a button to actually add that card to this table. 979 00:47:33,950 --> 00:47:38,887 So now what state do I need to keep about the card Editor? 980 00:47:38,887 --> 00:47:40,470 What can change about the card Editor? 981 00:47:40,470 --> 00:47:43,000 982 00:47:43,000 --> 00:47:48,560 Similar in spirit to what we had with the to-do list, 983 00:47:48,560 --> 00:47:50,420 what are two pieces of state that I need? 984 00:47:50,420 --> 00:47:51,018 Yeah? 985 00:47:51,018 --> 00:47:52,297 AUDIENCE: The input. 986 00:47:52,297 --> 00:47:53,130 BRIAN YU: The input. 987 00:47:53,130 --> 00:47:55,260 Yeah, what it is that I'm typing into the front field, 988 00:47:55,260 --> 00:47:57,343 and what it is that I'm typing into the backfield, 989 00:47:57,343 --> 00:48:00,600 that all needs to be state inside of my card Editor. 990 00:48:00,600 --> 00:48:03,210 So I'll go ahead and create a constructor 991 00:48:03,210 --> 00:48:05,670 that takes in some properties. 992 00:48:05,670 --> 00:48:09,300 And I'll set the initial value of this .state equal to, all right, well, 993 00:48:09,300 --> 00:48:12,570 the front of the card by default is just going to be empty. 994 00:48:12,570 --> 00:48:15,960 And the back of the card is by default also just going to be empty. 995 00:48:15,960 --> 00:48:18,740 996 00:48:18,740 --> 00:48:22,610 And that's going to be the value of this .state. 997 00:48:22,610 --> 00:48:25,065 If I scroll down to these two input fields, 998 00:48:25,065 --> 00:48:28,190 this is the input field where I type in what goes on the front of the card. 999 00:48:28,190 --> 00:48:31,850 This is the input field where I type in what goes on the back of the card. 1000 00:48:31,850 --> 00:48:38,360 The value of this input field is going to be this .state.front, 1001 00:48:38,360 --> 00:48:42,880 whatever it was on the front of the state. 1002 00:48:42,880 --> 00:48:48,351 And the value for the back, this .state.back. 1003 00:48:48,351 --> 00:48:51,100 I'm basically doing the same thing I did with all the input fields 1004 00:48:51,100 --> 00:48:55,750 before, just giving them a value so that I can later refer back to them. 1005 00:48:55,750 --> 00:49:00,820 Both of them need an on change property for what happens when I actually start 1006 00:49:00,820 --> 00:49:04,150 typing something into this input field. 1007 00:49:04,150 --> 00:49:09,910 And I'll just say this .handlechange as the name of the function for when I 1008 00:49:09,910 --> 00:49:13,660 actually start typing something into the front field or into the backfield. 1009 00:49:13,660 --> 00:49:18,904 For the back one, I'll do the same thing, onchange=this.handlechange. 1010 00:49:18,904 --> 00:49:20,820 And now let's write the handle change function 1011 00:49:20,820 --> 00:49:26,280 for what should happen when I start typing something into the input field. 1012 00:49:26,280 --> 00:49:31,650 And let me do that underneath at the end of the render function. 1013 00:49:31,650 --> 00:49:37,120 Handle change is going to be a function that takes its event. 1014 00:49:37,120 --> 00:49:45,770 And handle change is going to need to modify the state of the application. 1015 00:49:45,770 --> 00:49:52,060 And if I wanted to change the front of the value front inside of the state, 1016 00:49:52,060 --> 00:49:57,880 I could say this .state front is equal to event.target.value. 1017 00:49:57,880 --> 00:50:00,180 And that would change the front value. 1018 00:50:00,180 --> 00:50:02,740 And if I wanted to change what was on the back of the card, 1019 00:50:02,740 --> 00:50:07,280 I would have to do this .state back equals something else. 1020 00:50:07,280 --> 00:50:12,850 And so this is a little bit problematic, because I'm using this .handlechange 1021 00:50:12,850 --> 00:50:15,640 for both front and back. 1022 00:50:15,640 --> 00:50:19,300 I'm using the same event handler, this .handlechange for both of them. 1023 00:50:19,300 --> 00:50:24,070 And so I need some way of differentiating between these two event 1024 00:50:24,070 --> 00:50:27,640 handlers or saying, if I type something into the front input field, 1025 00:50:27,640 --> 00:50:30,770 then I want to change the value of this .state.front. 1026 00:50:30,770 --> 00:50:33,400 And if I type something into the back input field, 1027 00:50:33,400 --> 00:50:36,310 then I want to change this .state.back. 1028 00:50:36,310 --> 00:50:39,610 And so taking a look at these input fields, 1029 00:50:39,610 --> 00:50:44,050 is there any property that would be helpful for doing that? 1030 00:50:44,050 --> 00:50:47,267 Take a look on 63 and 64, any attribute these elements 1031 00:50:47,267 --> 00:50:48,350 have that would be useful. 1032 00:50:48,350 --> 00:50:48,950 Yeah? 1033 00:50:48,950 --> 00:50:51,100 AUDIENCE: You could somehow put the name [INAUDIBLE].. 1034 00:50:51,100 --> 00:50:51,910 BRIAN YU: Yeah, exactly. 1035 00:50:51,910 --> 00:50:53,770 I could somehow take advantage of the fact 1036 00:50:53,770 --> 00:50:56,740 that the name attribute of this input field is front 1037 00:50:56,740 --> 00:50:59,260 and the name attribute of this input field is back. 1038 00:50:59,260 --> 00:51:03,550 And I would like to if the name is front, set the state for front 1039 00:51:03,550 --> 00:51:05,650 to be event.target.value. 1040 00:51:05,650 --> 00:51:09,520 And if it's back, then set it to the back value. 1041 00:51:09,520 --> 00:51:13,600 And so JavaScript has some special syntax for doing this. 1042 00:51:13,600 --> 00:51:15,970 It's not something you've likely seen before. 1043 00:51:15,970 --> 00:51:23,120 But if I in brackets say [event.target.name], 1044 00:51:23,120 --> 00:51:27,710 well that's going to say whatever the value of event.target.name is, 1045 00:51:27,710 --> 00:51:30,530 let's go ahead and use that as the key. 1046 00:51:30,530 --> 00:51:34,700 And then event.target.value is going to go ahead and be the value. 1047 00:51:34,700 --> 00:51:37,310 So I can use a single handler to be able to handle 1048 00:51:37,310 --> 00:51:41,675 changing both the front and the back value of the state. 1049 00:51:41,675 --> 00:51:43,550 So something you might see from time to time, 1050 00:51:43,550 --> 00:51:46,250 this is common when you have multiple different input fields. 1051 00:51:46,250 --> 00:51:49,700 And rather than create a handle change front function and a handle 1052 00:51:49,700 --> 00:51:52,010 change back function, which would just be repetitive, 1053 00:51:52,010 --> 00:51:55,480 you can just have a single function that takes care of all of that. 1054 00:51:55,480 --> 00:51:56,093 Yeah? 1055 00:51:56,093 --> 00:51:57,542 AUDIENCE: [INAUDIBLE]. 1056 00:51:57,542 --> 00:52:06,719 1057 00:52:06,719 --> 00:52:08,260 BRIAN YU: Yeah, so I could add logic. 1058 00:52:08,260 --> 00:52:14,052 I could equivalently do this by doing ifevent.target.name=front, 1059 00:52:14,052 --> 00:52:17,010 then do something, and else do something else, and that would work too. 1060 00:52:17,010 --> 00:52:19,920 1061 00:52:19,920 --> 00:52:22,859 And again in React as with almost any programming project, 1062 00:52:22,859 --> 00:52:24,900 there are many ways of achieving the same things. 1063 00:52:24,900 --> 00:52:27,110 So pick the thing that makes the most sense to you 1064 00:52:27,110 --> 00:52:28,530 is often the best piece of advice. 1065 00:52:28,530 --> 00:52:31,130 1066 00:52:31,130 --> 00:52:33,020 So all right, I have a card Editor now where 1067 00:52:33,020 --> 00:52:36,290 I can type something into the front of the card and something else 1068 00:52:36,290 --> 00:52:37,490 into the back of the card. 1069 00:52:37,490 --> 00:52:41,570 And clicking Add card right now does nothing. 1070 00:52:41,570 --> 00:52:50,660 So let me go ahead and write a function that is going to add a new card. 1071 00:52:50,660 --> 00:52:55,370 Now to add a new card, do I need to modify the state of card Editor, card 1072 00:52:55,370 --> 00:52:57,470 Viewer, or app? 1073 00:52:57,470 --> 00:52:59,900 Again, I have three components. 1074 00:52:59,900 --> 00:53:03,950 Which state do I need to modify to add a new card? 1075 00:53:03,950 --> 00:53:04,860 App state, right. 1076 00:53:04,860 --> 00:53:08,210 Because app, that class, is the one that actually 1077 00:53:08,210 --> 00:53:11,430 has cards inside the state of the application. 1078 00:53:11,430 --> 00:53:18,118 So we're going to need to add a Add card method to this application. 1079 00:53:18,118 --> 00:53:21,790 1080 00:53:21,790 --> 00:53:25,330 And the Add card method, we'll have it take two arguments. 1081 00:53:25,330 --> 00:53:26,980 We can choose what the arguments are. 1082 00:53:26,980 --> 00:53:29,521 But it's probably going to make sense for the Add card method 1083 00:53:29,521 --> 00:53:34,300 to take an argument for the front and an argument for the back. 1084 00:53:34,300 --> 00:53:37,710 And then do something with those two values. 1085 00:53:37,710 --> 00:53:41,130 So to add a card with a front equal to front and a back equal to back, 1086 00:53:41,130 --> 00:53:45,200 I can do this .setstate. 1087 00:53:45,200 --> 00:53:49,960 I want to update the state of my application. 1088 00:53:49,960 --> 00:53:52,730 And I want to set cards equal to, well, I 1089 00:53:52,730 --> 00:53:56,660 want all the existing cards plus my new card. 1090 00:53:56,660 --> 00:54:03,410 So I'll say ...state.cards to say fill in all of the existing cards 1091 00:54:03,410 --> 00:54:04,820 into the array. 1092 00:54:04,820 --> 00:54:07,130 And now I'd like to add my new card to this array 1093 00:54:07,130 --> 00:54:11,450 as well, where the front is going to be equal to front, 1094 00:54:11,450 --> 00:54:15,530 and the back is going to be equal to back. 1095 00:54:15,530 --> 00:54:18,890 So I'm updating the state, saying take the old state, 1096 00:54:18,890 --> 00:54:21,800 go ahead and fill in all of those cards, and then just tack 1097 00:54:21,800 --> 00:54:25,640 on to the end of the array a new object where the front of the card 1098 00:54:25,640 --> 00:54:29,822 is this variable front, and the back of this card is this variable back. 1099 00:54:29,822 --> 00:54:30,794 Yeah? 1100 00:54:30,794 --> 00:54:32,252 AUDIENCE: [INAUDIBLE]. 1101 00:54:32,252 --> 00:54:39,560 1102 00:54:39,560 --> 00:54:41,510 BRIAN YU: Yeah, excellent point. 1103 00:54:41,510 --> 00:54:44,337 So I mentioned this a moment ago of JavaScript object shorthand, 1104 00:54:44,337 --> 00:54:46,670 because front's key and front's value are the same name, 1105 00:54:46,670 --> 00:54:49,970 they're both called front and back, they're both called the same thing, 1106 00:54:49,970 --> 00:54:53,030 this happens often enough in JavaScript that there's shorthand for it. 1107 00:54:53,030 --> 00:54:56,649 I can just say, front, back and it's just 1108 00:54:56,649 --> 00:54:58,940 going to assume the keys and values have the same name. 1109 00:54:58,940 --> 00:55:00,610 And so this will do exactly the same thing. 1110 00:55:00,610 --> 00:55:02,318 But yeah, that's the shorthand I can use. 1111 00:55:02,318 --> 00:55:03,018 Yeah? 1112 00:55:03,018 --> 00:55:07,464 AUDIENCE: Can you repeat [INAUDIBLE]. 1113 00:55:07,464 --> 00:55:09,934 I'm a little bit confused with event. 1114 00:55:09,934 --> 00:55:14,124 Why does switch mode not take an event, if it also [INAUDIBLE]?? 1115 00:55:14,124 --> 00:55:16,290 BRIAN YU: So why does switch mode not take an event. 1116 00:55:16,290 --> 00:55:18,512 Switch mode could take an argument called event. 1117 00:55:18,512 --> 00:55:20,220 JavaScript option has functions that have 1118 00:55:20,220 --> 00:55:23,580 these optional arguments that if you wanted to take an event argument, 1119 00:55:23,580 --> 00:55:25,130 it can. 1120 00:55:25,130 --> 00:55:27,632 But switch mode doesn't need to access the event. 1121 00:55:27,632 --> 00:55:30,090 Because the only thing the switch mode function needs to do 1122 00:55:30,090 --> 00:55:32,760 is take, whether it's on the Editor and the Viewer, 1123 00:55:32,760 --> 00:55:37,530 and switch it to the other Viewer, the other component that I have. 1124 00:55:37,530 --> 00:55:42,120 And so nothing about the event actually matters for the logic 1125 00:55:42,120 --> 00:55:43,890 of the switch mode function. 1126 00:55:43,890 --> 00:55:49,350 Whereas by contrast, handle change actually does care about the event. 1127 00:55:49,350 --> 00:55:53,050 The event of me changing the input field is important for two reasons. 1128 00:55:53,050 --> 00:55:58,860 One, I care about the event, because I care about the name of the input field 1129 00:55:58,860 --> 00:56:00,390 that I was typing something into. 1130 00:56:00,390 --> 00:56:03,919 Was I typing something into the front field or the backfield? 1131 00:56:03,919 --> 00:56:06,210 And depending on that, I want slightly different logic. 1132 00:56:06,210 --> 00:56:10,020 And it also matters because I care about what is it that I actually typed in. 1133 00:56:10,020 --> 00:56:14,280 Because what it is that I typed in should be the new value of either front 1134 00:56:14,280 --> 00:56:15,570 or back in the state. 1135 00:56:15,570 --> 00:56:18,570 So if you need to access the event for some reason, 1136 00:56:18,570 --> 00:56:22,350 usually to get at event.target, the thing that's triggering the event, 1137 00:56:22,350 --> 00:56:24,651 then you'll need the event parameter in the function. 1138 00:56:24,651 --> 00:56:27,900 But if you don't need the event, then it doesn't matter whether you include it 1139 00:56:27,900 --> 00:56:28,400 or not. 1140 00:56:28,400 --> 00:56:32,940 And so generally speaking, we won't include it. 1141 00:56:32,940 --> 00:56:34,040 Yeah? 1142 00:56:34,040 --> 00:56:39,583 AUDIENCE: For all the examples you've been doing [INAUDIBLE] 1143 00:56:39,583 --> 00:56:43,479 Is there a reason we're doing that instead of on the bottom click 1144 00:56:43,479 --> 00:56:47,870 maybe change the state of the [INAUDIBLE].. 1145 00:56:47,870 --> 00:56:50,120 BRIAN YU: So when the button is clicked, we 1146 00:56:50,120 --> 00:56:53,840 want to be able to just look at the state of the application 1147 00:56:53,840 --> 00:56:58,760 to be able to know what is the front value and what if the back value. 1148 00:56:58,760 --> 00:57:02,270 And so generally in React, any time something 1149 00:57:02,270 --> 00:57:06,770 changes in the user interface, that should be represented 1150 00:57:06,770 --> 00:57:08,626 by some underlying change in state. 1151 00:57:08,626 --> 00:57:11,000 In other words, if you know the state of the application, 1152 00:57:11,000 --> 00:57:13,610 what the value of this .state is for all of your components, 1153 00:57:13,610 --> 00:57:17,450 I should be able to tell you exactly what the page is going to look like. 1154 00:57:17,450 --> 00:57:21,116 And so that's just sort of part of the React paradigm. 1155 00:57:21,116 --> 00:57:22,792 Yeah? 1156 00:57:22,792 --> 00:57:23,990 AUDIENCE: [INAUDIBLE]. 1157 00:57:23,990 --> 00:57:29,179 1158 00:57:29,179 --> 00:57:31,970 BRIAN YU: It depends on what you try to do with properties that you 1159 00:57:31,970 --> 00:57:32,960 don't provide in. 1160 00:57:32,960 --> 00:57:35,870 So if you try to use a property that you don't provide and just, 1161 00:57:35,870 --> 00:57:40,240 like, paste it into the HTML content somewhere inside your render function, 1162 00:57:40,240 --> 00:57:43,520 odds are it will work but just nothing will show up there. 1163 00:57:43,520 --> 00:57:46,640 But if you try and do any logic with it, like, if you try and call 1164 00:57:46,640 --> 00:57:49,845 or pass it in as arguments to functions or perform operations with it 1165 00:57:49,845 --> 00:57:52,220 and they don't exist, then you could start to get errors. 1166 00:57:52,220 --> 00:57:54,428 So you do want to be a little bit careful about that. 1167 00:57:54,428 --> 00:57:57,314 1168 00:57:57,314 --> 00:57:57,855 Other things? 1169 00:57:57,855 --> 00:58:01,570 1170 00:58:01,570 --> 00:58:04,450 OK, so we have this Add card function. 1171 00:58:04,450 --> 00:58:06,700 And in particular, this Add card function 1172 00:58:06,700 --> 00:58:09,910 is a function that our card Editor needs to have access to. 1173 00:58:09,910 --> 00:58:13,520 And so I'll go ahead and add to this card Editor. 1174 00:58:13,520 --> 00:58:15,520 The card Editor knows how to switch modes. 1175 00:58:15,520 --> 00:58:18,720 But the card Editor also needs to know how to add a card. 1176 00:58:18,720 --> 00:58:20,755 So Add card will be equal to this .addcard. 1177 00:58:20,755 --> 00:58:23,740 1178 00:58:23,740 --> 00:58:34,370 And now inside of our card Editor, when you click on the button, on-click, 1179 00:58:34,370 --> 00:58:35,490 I'll call this .addcard. 1180 00:58:35,490 --> 00:58:40,110 1181 00:58:40,110 --> 00:58:41,900 So this is a different Add card function. 1182 00:58:41,900 --> 00:58:45,250 1183 00:58:45,250 --> 00:58:49,560 But what needs to happen when I add a card in a Viewer? 1184 00:58:49,560 --> 00:58:51,850 Well, two things need to happen. 1185 00:58:51,850 --> 00:58:56,610 One is I need to actually call the Add card function in my props. 1186 00:58:56,610 --> 00:59:02,220 This .props.addcard, passing in whatever was in the front input field 1187 00:59:02,220 --> 00:59:04,350 and whatever was in the back input field. 1188 00:59:04,350 --> 00:59:09,820 And that information is stored in this .state.front and this .state.back. 1189 00:59:09,820 --> 00:59:13,030 1190 00:59:13,030 --> 00:59:16,787 And then what else should I do from a user experience perspective 1191 00:59:16,787 --> 00:59:19,620 if I type in something into the front input field, type in something 1192 00:59:19,620 --> 00:59:21,477 into the back, and click Add card? 1193 00:59:21,477 --> 00:59:22,820 AUDIENCE: Clear out the states. 1194 00:59:22,820 --> 00:59:24,153 BRIAN YU: Clear out the state's. 1195 00:59:24,153 --> 00:59:28,220 Clear out the input field so that we say this .setstate. 1196 00:59:28,220 --> 00:59:30,050 Front is going to be empty. 1197 00:59:30,050 --> 00:59:31,762 Back is going to be empty. 1198 00:59:31,762 --> 00:59:33,470 And so we're saying clear out those input 1199 00:59:33,470 --> 00:59:37,280 fields so that we can start fresh. 1200 00:59:37,280 --> 00:59:39,380 Go ahead and refresh the page. 1201 00:59:39,380 --> 00:59:41,990 Front of the card, it will be test three front. 1202 00:59:41,990 --> 00:59:44,420 Back of the card, test three back. 1203 00:59:44,420 --> 00:59:46,482 I'll go ahead and click Add card. 1204 00:59:46,482 --> 00:59:50,150 And all right, great, we got a new card in this list of cards. 1205 00:59:50,150 --> 00:59:54,200 And the input fields cleared themselves out. 1206 00:59:54,200 --> 00:59:57,590 At this point, I'm going to go back and delete these sample cards 1207 00:59:57,590 --> 01:00:00,780 that we had just for testing purposes. 1208 01:00:00,780 --> 01:00:04,111 We'll go back to just starting with an empty list. 1209 01:00:04,111 --> 01:00:06,360 And now I can begin to add whatever flashcards I want. 1210 01:00:06,360 --> 01:00:10,430 I can say, OK, 1 plus 1, plus 2. 1211 01:00:10,430 --> 01:00:12,967 We can do as many of these as you want to. 1212 01:00:12,967 --> 01:00:15,050 But of course, the Delete button doesn't yet work. 1213 01:00:15,050 --> 01:00:17,960 We can create all the cards, but we can't yet delete a card. 1214 01:00:17,960 --> 01:00:19,400 And so to do that, it's going to be basically 1215 01:00:19,400 --> 01:00:21,524 the exact same thing as what we just did for adding 1216 01:00:21,524 --> 01:00:25,400 a card, but the analog for deleting, as we did with the tasks example. 1217 01:00:25,400 --> 01:00:28,640 So inside of the app, we had a function called Add 1218 01:00:28,640 --> 01:00:31,310 card, which took care of adding a card. 1219 01:00:31,310 --> 01:00:35,770 But our app is also going to need to know how to delete a card. 1220 01:00:35,770 --> 01:00:39,770 And to delete a card, we're going to delete a card based on its index. 1221 01:00:39,770 --> 01:00:42,020 And this code should look very familiar to the code we 1222 01:00:42,020 --> 01:00:44,300 did when we were doing task management. 1223 01:00:44,300 --> 01:00:47,240 We're going to say, all right, this .setstate. 1224 01:00:47,240 --> 01:00:50,000 It's going to take the original state. 1225 01:00:50,000 --> 01:00:53,150 And let's go ahead and say, all right, the cards, 1226 01:00:53,150 --> 01:00:56,460 let's make a copy of state.cards. 1227 01:00:56,460 --> 01:00:58,760 And let's go ahead and splice out of the cards 1228 01:00:58,760 --> 01:01:02,600 remove something from the cards array at index. 1229 01:01:02,600 --> 01:01:07,870 Remove one thing and go ahead and return cards 1230 01:01:07,870 --> 01:01:11,650 is equal to whatever the value of cards is. 1231 01:01:11,650 --> 01:01:12,910 So what's happening here? 1232 01:01:12,910 --> 01:01:16,180 When I delete a card, at this particular index, I'm saying, 1233 01:01:16,180 --> 01:01:20,620 OK, make a copy of state.cards, store it in this variable called cards, 1234 01:01:20,620 --> 01:01:22,960 remove what was ever at this index, remove 1235 01:01:22,960 --> 01:01:25,930 one element using the splice method. 1236 01:01:25,930 --> 01:01:29,650 And then I'm returning the new state, update the value of cards in the state 1237 01:01:29,650 --> 01:01:31,870 to be equal to this variable cards. 1238 01:01:31,870 --> 01:01:34,690 And as we've seen a couple of times now, because these things have 1239 01:01:34,690 --> 01:01:39,250 the same name, you could even simplify this to just return cards. 1240 01:01:39,250 --> 01:01:43,660 And we'll implicitly assume that they have the same name. 1241 01:01:43,660 --> 01:01:46,380 So now I have this delete card method in my app 1242 01:01:46,380 --> 01:01:49,860 that operates in order to delete a card. 1243 01:01:49,860 --> 01:01:53,710 This is also a function that card Editor needs to have access to. 1244 01:01:53,710 --> 01:01:56,850 So we'll say delete card equals this .deletecard. 1245 01:01:56,850 --> 01:01:59,650 1246 01:01:59,650 --> 01:02:08,590 And we'll go ahead and now go to the card Editor. 1247 01:02:08,590 --> 01:02:11,500 And we'll do the same thing we did before, this button will 1248 01:02:11,500 --> 01:02:16,080 give a data index property of-- 1249 01:02:16,080 --> 01:02:18,830 I'm sorry, not the Add card button. 1250 01:02:18,830 --> 01:02:22,640 The Delete button-- yeah, here's the Delete button-- 1251 01:02:22,640 --> 01:02:25,940 will give it a data/index property of, all right, 1252 01:02:25,940 --> 01:02:30,500 what is the index of which element to delete if I try and delete this card? 1253 01:02:30,500 --> 01:02:32,690 It'll be I for example. 1254 01:02:32,690 --> 01:02:40,794 And then when I click on it, we're going to call the this .deletecard method. 1255 01:02:40,794 --> 01:02:42,710 Same as the example from earlier this morning. 1256 01:02:42,710 --> 01:02:46,080 1257 01:02:46,080 --> 01:02:49,010 And now when I delete a card, that's going 1258 01:02:49,010 --> 01:02:52,220 to be a function that takes the event as input. 1259 01:02:52,220 --> 01:02:53,690 And why do we need the event? 1260 01:02:53,690 --> 01:02:57,780 Well, because event.target.dataset.index. 1261 01:02:57,780 --> 01:03:00,680 In other words, take the click event, get out 1262 01:03:00,680 --> 01:03:04,130 its target, the button that I clicked on, get at its data 1263 01:03:04,130 --> 01:03:08,930 attributes, and specifically, get at the data-index attribute of the button 1264 01:03:08,930 --> 01:03:10,040 then I clicked on. 1265 01:03:10,040 --> 01:03:13,760 This is the index of the card I want to delete. 1266 01:03:13,760 --> 01:03:19,140 And so to actually do the deletion, I'll say this .props.deletecard. 1267 01:03:19,140 --> 01:03:22,154 1268 01:03:22,154 --> 01:03:25,810 I'm deleting whatever was at that index. 1269 01:03:25,810 --> 01:03:29,010 So I have a delete card function inside of the card Editor 1270 01:03:29,010 --> 01:03:33,150 that calls the delete card function that was provided to me as one of the props. 1271 01:03:33,150 --> 01:03:36,330 And the only difference is this function, delete card, 1272 01:03:36,330 --> 01:03:40,890 is going to take care of providing to the apps delete card 1273 01:03:40,890 --> 01:03:43,932 the index that I actually want to delete. 1274 01:03:43,932 --> 01:03:44,894 Yeah? 1275 01:03:44,894 --> 01:03:47,299 AUDIENCE: [INAUDIBLE]. 1276 01:03:47,299 --> 01:03:48,261 BRIAN YU: Repeat that? 1277 01:03:48,261 --> 01:03:49,704 AUDIENCE: [INAUDIBLE]. 1278 01:03:49,704 --> 01:03:53,080 1279 01:03:53,080 --> 01:03:56,220 BRIAN YU: We don't need to wrap it because we're not actually calling this 1280 01:03:56,220 --> 01:03:56,920 .deletecard. 1281 01:03:56,920 --> 01:04:00,520 I'm not saying this .deletecardI, which you could do. 1282 01:04:00,520 --> 01:04:02,710 I'm just saying this .deletecard. 1283 01:04:02,710 --> 01:04:05,590 And so that is a function that we'll run when the button is clicked. 1284 01:04:05,590 --> 01:04:09,310 And so there's no need to wrap that inside of an outer function. 1285 01:04:09,310 --> 01:04:09,987 Yeah? 1286 01:04:09,987 --> 01:04:12,969 AUDIENCE: Why can you find delete card twice separately 1287 01:04:12,969 --> 01:04:16,658 rather than just call the card function that's 1288 01:04:16,658 --> 01:04:20,150 defined in the app and [INAUDIBLE] 1289 01:04:20,150 --> 01:04:21,860 BRIAN YU: So you could do it that way. 1290 01:04:21,860 --> 01:04:27,930 You could wrap this in a function and say, this .props.deletecardI. 1291 01:04:27,930 --> 01:04:29,180 And that would work just fine. 1292 01:04:29,180 --> 01:04:31,263 Basically, having a function that when you call it 1293 01:04:31,263 --> 01:04:33,789 is going to go to props.deletecard and delete that element. 1294 01:04:33,789 --> 01:04:36,080 But I'm putting it separately for the efficiency reason 1295 01:04:36,080 --> 01:04:39,680 that I described before of not regenerating these functions over 1296 01:04:39,680 --> 01:04:40,668 and over. 1297 01:04:40,668 --> 01:04:46,596 1298 01:04:46,596 --> 01:04:49,010 Let's check to make sure this actually works. 1299 01:04:49,010 --> 01:04:51,440 So let's do test, test. 1300 01:04:51,440 --> 01:04:53,030 Another one, another one. 1301 01:04:53,030 --> 01:04:55,250 If I delete a card, all right, it gets removed. 1302 01:04:55,250 --> 01:05:00,050 If I I delete another card, we're able to add and delete cards 1303 01:05:00,050 --> 01:05:04,010 from the card Editor. 1304 01:05:04,010 --> 01:05:05,600 Questions about anything? 1305 01:05:05,600 --> 01:05:06,238 Yeah? 1306 01:05:06,238 --> 01:05:07,612 AUDIENCE: [INAUDIBLE]. 1307 01:05:07,612 --> 01:05:10,360 1308 01:05:10,360 --> 01:05:11,590 BRIAN YU: Good question. 1309 01:05:11,590 --> 01:05:16,780 So the delete card function inside of the app class 1310 01:05:16,780 --> 01:05:21,580 is a delete card function that just takes an index and removes 1311 01:05:21,580 --> 01:05:23,670 whatever card is at that index. 1312 01:05:23,670 --> 01:05:27,502 And I had another function in card Editor 1313 01:05:27,502 --> 01:05:29,210 that I could have given a different name. 1314 01:05:29,210 --> 01:05:31,876 But it's deleting a card, so I decided to give it the same name. 1315 01:05:31,876 --> 01:05:37,510 And all this function is doing is it is calling the original function, 1316 01:05:37,510 --> 01:05:41,647 passing in which card to actually delete. 1317 01:05:41,647 --> 01:05:44,230 You could conceive of other models where you consolidate these 1318 01:05:44,230 --> 01:05:45,330 into one function. 1319 01:05:45,330 --> 01:05:48,040 I separated into two for the sake of separating 1320 01:05:48,040 --> 01:05:51,380 the behavior of deleting a card at a particular index 1321 01:05:51,380 --> 01:05:55,180 and responding to the fact that you clicked on a button that is supposed 1322 01:05:55,180 --> 01:05:56,926 to do the deleting of the card. 1323 01:05:56,926 --> 01:05:59,800 Though if you'd like to practice, it would be an interesting exercise 1324 01:05:59,800 --> 01:06:01,960 to consolidate this to just a single function. 1325 01:06:01,960 --> 01:06:03,376 And you can try doing it that way. 1326 01:06:03,376 --> 01:06:07,174 1327 01:06:07,174 --> 01:06:09,340 All right, so now we have the ability to edit cards. 1328 01:06:09,340 --> 01:06:11,690 And all that remains is this card Viewer. 1329 01:06:11,690 --> 01:06:18,370 And so we have this, this is the Viewer page where in theory you'd 1330 01:06:18,370 --> 01:06:20,950 be able to view whatever contents of the cards that you have, 1331 01:06:20,950 --> 01:06:26,730 because card Viewer is going to provide this cards argument that 1332 01:06:26,730 --> 01:06:30,160 is going to contain all of the cards in the current state. 1333 01:06:30,160 --> 01:06:33,142 1334 01:06:33,142 --> 01:06:34,136 Questions? 1335 01:06:34,136 --> 01:06:37,130 1336 01:06:37,130 --> 01:06:40,900 OK, so there's a lot of code here, a lot of interacting and moving pieces. 1337 01:06:40,900 --> 01:06:43,390 We have an app that is this big component that 1338 01:06:43,390 --> 01:06:46,780 contains within it two smaller components, a card Editor and a card 1339 01:06:46,780 --> 01:06:47,620 Viewer. 1340 01:06:47,620 --> 01:06:51,460 And there's a lot of interaction between these components. 1341 01:06:51,460 --> 01:06:54,520 The app is providing props to the card Editor, 1342 01:06:54,520 --> 01:06:58,120 providing information about the cards, providing event handlers 1343 01:06:58,120 --> 01:07:00,670 for what to do in order to add a card or remove a card. 1344 01:07:00,670 --> 01:07:04,510 And in response, the card Editor is calling a lot of those functions 1345 01:07:04,510 --> 01:07:08,410 that it was provided in order to say, OK, update the application state, 1346 01:07:08,410 --> 01:07:12,160 update the cards or change the mode from the Editor to the Viewer, 1347 01:07:12,160 --> 01:07:12,817 or vise versa. 1348 01:07:12,817 --> 01:07:15,400 So I definitely encourage you to take a look at this example-- 1349 01:07:15,400 --> 01:07:16,984 I'll post it online in just a moment-- 1350 01:07:16,984 --> 01:07:18,108 and try and tease it apart. 1351 01:07:18,108 --> 01:07:19,630 Try and figure out how it's working. 1352 01:07:19,630 --> 01:07:22,930 In fact, potentially try and add new features to it if you'd like. 1353 01:07:22,930 --> 01:07:26,680 And the main project of this afternoon is going to be to extend on this. 1354 01:07:26,680 --> 01:07:30,640 The first step is going to be understand the code that exists there. 1355 01:07:30,640 --> 01:07:35,030 But then let's think about trying to add some more possibilities. 1356 01:07:35,030 --> 01:07:39,599 So adding flash cards is a feature that we already have. 1357 01:07:39,599 --> 01:07:41,890 Displaying the flash cards in a table, the second thing 1358 01:07:41,890 --> 01:07:43,610 here is a feature that we already have. 1359 01:07:43,610 --> 01:07:46,720 And it's these last two bits that are worth trying to implement here. 1360 01:07:46,720 --> 01:07:50,290 Try and implement the card Viewer, some way of viewing the flash cards. 1361 01:07:50,290 --> 01:07:52,660 And at first, just see if you can get one flash 1362 01:07:52,660 --> 01:07:56,389 card to display the front of card number one, for example. 1363 01:07:56,389 --> 01:07:58,180 And then see if you can add some notion of, 1364 01:07:58,180 --> 01:08:01,420 all right, when you click on something, have an on-click handler 1365 01:08:01,420 --> 01:08:03,190 that flips the card over. 1366 01:08:03,190 --> 01:08:05,711 In other words, goes from storing the front to the back. 1367 01:08:05,711 --> 01:08:08,710 And you might think about the kind of state that you want to store that. 1368 01:08:08,710 --> 01:08:11,376 You probably want something inside your application state that's 1369 01:08:11,376 --> 01:08:14,170 keeping track of are you on the front of the card 1370 01:08:14,170 --> 01:08:15,746 or are you on the back of the card? 1371 01:08:15,746 --> 01:08:17,620 And when you click on the card, you just need 1372 01:08:17,620 --> 01:08:20,560 to flip that state around going from front to back. 1373 01:08:20,560 --> 01:08:23,590 In much the same way that we went from Editor to Viewer, 1374 01:08:23,590 --> 01:08:27,040 when you clicked on a button, you can go from front to back of the card 1375 01:08:27,040 --> 01:08:29,236 by clicking on the card. 1376 01:08:29,236 --> 01:08:32,319 You can display one card, and show the card, and flip it over to the back. 1377 01:08:32,319 --> 01:08:34,960 Consider a button that moves you on to the next flash cards. 1378 01:08:34,960 --> 01:08:37,001 So you're on card number one, you press a button, 1379 01:08:37,001 --> 01:08:38,649 it takes you to card number two. 1380 01:08:38,649 --> 01:08:41,200 And that's very similar in spirit to just this idea 1381 01:08:41,200 --> 01:08:44,390 of thinking about what you need to store inside of your application state. 1382 01:08:44,390 --> 01:08:47,080 In addition to having information about are you on the front of the card 1383 01:08:47,080 --> 01:08:49,840 or the back of the card, you probably also want some information 1384 01:08:49,840 --> 01:08:52,810 about which card are you currently on? 1385 01:08:52,810 --> 01:08:55,090 Some notion inside the state of I am currently 1386 01:08:55,090 --> 01:08:59,680 on card zero, or card one, or card two, whereby you can change that state value 1387 01:08:59,680 --> 01:09:01,904 in order to show a different card. 1388 01:09:01,904 --> 01:09:03,279 So go ahead and give that a shot. 1389 01:09:03,279 --> 01:09:04,840 If you manage to finish that, there are certainly 1390 01:09:04,840 --> 01:09:06,282 other features you can consider. 1391 01:09:06,282 --> 01:09:07,240 I listed a couple here. 1392 01:09:07,240 --> 01:09:10,060 Consider a button that will shuffle the cards and put them in a random order, 1393 01:09:10,060 --> 01:09:10,930 for instance. 1394 01:09:10,930 --> 01:09:14,649 Or marking cards as learned or not, the one you might see on a quiz app 1395 01:09:14,649 --> 01:09:16,100 like Quizlet, for example. 1396 01:09:16,100 --> 01:09:18,792 And so plenty of room to explore here as well. 1397 01:09:18,792 --> 01:09:21,250 Feel free to continue working on the to-do list application 1398 01:09:21,250 --> 01:09:22,359 if you'd like to. 1399 01:09:22,359 --> 01:09:25,029 The staff will be around to certainly help you up until 5:00. 1400 01:09:25,029 --> 01:09:27,760 And tomorrow, we're going to spend even more time on React. 1401 01:09:27,760 --> 01:09:29,914 So if this all seems new and unfamiliar to you, 1402 01:09:29,914 --> 01:09:32,830 know that tomorrow we'll be spending more time on the exact same topic 1403 01:09:32,830 --> 01:09:34,829 so that we can help you become familiar with it, 1404 01:09:34,829 --> 01:09:37,910 help you get used to the different way of thinking with regards to React. 1405 01:09:37,910 --> 01:09:40,276 And so all that and more with CS50 Beyond. 1406 01:09:40,276 --> 01:09:42,609 So we'll go ahead and turn to our afternoon project now. 1407 01:09:42,609 --> 01:09:44,650 Feel free to stick around here in the auditorium. 1408 01:09:44,650 --> 01:09:47,460 And come and find the staff if you need help with anything. 1409 01:09:47,460 --> 01:09:48,344