1 00:00:00,000 --> 00:00:00,660 2 00:00:00,660 --> 00:00:02,470 GABRIEL GOMARIZ: Hello, and welcome. 3 00:00:02,470 --> 00:00:06,420 This is frontend development with React and Pagedraw. 4 00:00:06,420 --> 00:00:10,830 My name is Gabriel Gomariz, and I'm Harvard class of 2017. 5 00:00:10,830 --> 00:00:13,020 I graduated in computer science. 6 00:00:13,020 --> 00:00:17,880 And now I'm living in San Francisco working on a startup called page draw. 7 00:00:17,880 --> 00:00:19,540 We work on automating firm development. 8 00:00:19,540 --> 00:00:22,030 I'll get into a little bit more of what that means. 9 00:00:22,030 --> 00:00:24,300 But before we dive into that, I would like 10 00:00:24,300 --> 00:00:28,680 to talk a little bit about React, which is a JavaScript framework that's 11 00:00:28,680 --> 00:00:33,630 doing a lot of buzz in the tech community these days. 12 00:00:33,630 --> 00:00:36,270 React is developed by Facebook. 13 00:00:36,270 --> 00:00:38,740 If you want to read more, you can always go to reactjs.org. 14 00:00:38,740 --> 00:00:40,410 That's their official website. 15 00:00:40,410 --> 00:00:44,410 And it is a JavaScript library for building user interfaces. 16 00:00:44,410 --> 00:00:48,570 So the idea is if you want to build cool, awesome modern apps-- 17 00:00:48,570 --> 00:00:51,210 something like Facebook, something like Airbnb-- 18 00:00:51,210 --> 00:00:55,370 that are not static, but they have a lot of stuff going on. 19 00:00:55,370 --> 00:01:00,120 You should probably be looking into using something like React. 20 00:01:00,120 --> 00:01:02,970 To understand why React is cool, I'd like 21 00:01:02,970 --> 00:01:07,950 to first go into a little bit of history of these things. 22 00:01:07,950 --> 00:01:13,470 So the quintessential way that you learn in cs50 probably of using JavaScript, 23 00:01:13,470 --> 00:01:17,180 if you recall JavaScript, you can use to ship code to the client side 24 00:01:17,180 --> 00:01:21,330 to the browser to do changes that do not need 25 00:01:21,330 --> 00:01:25,660 to refresh the page on your browser. 26 00:01:25,660 --> 00:01:31,410 So if you want, for example, to on something and have a pop up appear, 27 00:01:31,410 --> 00:01:33,390 or something dynamic show up on the screen 28 00:01:33,390 --> 00:01:36,810 without having to refresh the page, probably you're using JavaScript. 29 00:01:36,810 --> 00:01:40,590 The way that you do that is you traditionally 30 00:01:40,590 --> 00:01:48,470 do something like var in JavaScript, element or root 31 00:01:48,470 --> 00:01:52,130 equals document dot get element by ID. 32 00:01:52,130 --> 00:01:54,980 You pass it some ID, Hello World. 33 00:01:54,980 --> 00:01:59,410 34 00:01:59,410 --> 00:02:02,860 And then as soon as some event happens, for example someone clicks 35 00:02:02,860 --> 00:02:04,835 on a button, what you do is you say, root 36 00:02:04,835 --> 00:02:10,800 dot inner HTML equals my new content. 37 00:02:10,800 --> 00:02:15,940 OK, so this is kind of like the quintessential JavaScript example. 38 00:02:15,940 --> 00:02:21,170 And I want you to notice that this is very mutational. 39 00:02:21,170 --> 00:02:24,099 This is very imperative, we call it. 40 00:02:24,099 --> 00:02:26,140 And that's very important for understanding React 41 00:02:26,140 --> 00:02:30,040 because React is kind of the opposite of that way of thinking. 42 00:02:30,040 --> 00:02:34,090 Why I call this mutational is that you're first fetching 43 00:02:34,090 --> 00:02:36,370 some element that's on the screen. 44 00:02:36,370 --> 00:02:38,270 We can actually do this live here. 45 00:02:38,270 --> 00:02:41,560 So if I inspect Element and go to the console, 46 00:02:41,560 --> 00:02:56,980 I can actually do this in real JavaScript, where if I type in zero, 47 00:02:56,980 --> 00:02:59,320 this has essentially selected that element. 48 00:02:59,320 --> 00:03:05,800 And I can say, zero dot inner text equals hello world. 49 00:03:05,800 --> 00:03:06,870 And there you go. 50 00:03:06,870 --> 00:03:09,640 It changed right there using JavaScript into hello world. 51 00:03:09,640 --> 00:03:12,610 But this is mutational because I'm fetching some part of the screen, 52 00:03:12,610 --> 00:03:14,080 and I'm saying, go and change it. 53 00:03:14,080 --> 00:03:16,630 54 00:03:16,630 --> 00:03:18,710 React has a different way to do this. 55 00:03:18,710 --> 00:03:20,830 So first thing I'm going to do is I'm going 56 00:03:20,830 --> 00:03:25,276 to use this little tool called create React app that 57 00:03:25,276 --> 00:03:26,650 just creates a React app for you. 58 00:03:26,650 --> 00:03:30,730 59 00:03:30,730 --> 00:03:32,772 And I'll call my app movies. 60 00:03:32,772 --> 00:03:34,605 We're going to be working with movies today. 61 00:03:34,605 --> 00:03:37,591 Oh, there's already a directory called movies. 62 00:03:37,591 --> 00:03:39,340 Let me remove it. 63 00:03:39,340 --> 00:03:41,230 Permission denied. 64 00:03:41,230 --> 00:03:43,420 Let's just call it a different thing-- 65 00:03:43,420 --> 00:03:46,700 Movies example. 66 00:03:46,700 --> 00:03:48,970 So this is making sure the React is installed, 67 00:03:48,970 --> 00:03:53,440 and it's creating a directory that has all of the initial files 68 00:03:53,440 --> 00:03:55,870 that I'm going to need to do a React app. 69 00:03:55,870 --> 00:03:58,780 70 00:03:58,780 --> 00:03:59,290 There we go. 71 00:03:59,290 --> 00:04:05,530 So now we can cd into movies example. 72 00:04:05,530 --> 00:04:08,464 We're going to see that we have these node modules here, which 73 00:04:08,464 --> 00:04:09,880 essentially all of your libraries. 74 00:04:09,880 --> 00:04:11,450 There's some stuff happening. 75 00:04:11,450 --> 00:04:16,000 Package JSON is essentially giving me some metadata about my product. 76 00:04:16,000 --> 00:04:18,930 But the really important folder is in source. 77 00:04:18,930 --> 00:04:22,200 So if you're going to source, there are a couple of files here. 78 00:04:22,200 --> 00:04:29,120 The most important ones are this index, dot js and app dot js. 79 00:04:29,120 --> 00:04:32,780 So the idea of index dot js is very simple. 80 00:04:32,780 --> 00:04:37,060 It is just importing this app from dot flash app, 81 00:04:37,060 --> 00:04:40,230 and then calling ReactDOM dot render. 82 00:04:40,230 --> 00:04:42,550 All the rest is like also doing some stuff, 83 00:04:42,550 --> 00:04:45,880 but it's not as important as those two lines-- line 4 and line 7 here. 84 00:04:45,880 --> 00:04:47,880 So ReactDOM dot render is just saying, render 85 00:04:47,880 --> 00:04:52,600 this React component called app onto the screen into this document 86 00:04:52,600 --> 00:04:54,710 dot get element by ID root. 87 00:04:54,710 --> 00:04:57,010 That's kind of the only mutational thing we're 88 00:04:57,010 --> 00:05:00,700 going to do here in the similar style of the JavaScript that we wrote before. 89 00:05:00,700 --> 00:05:04,060 But app is a React component. 90 00:05:04,060 --> 00:05:06,400 So let's dive into what that is. 91 00:05:06,400 --> 00:05:10,180 So class app extends component that's imported from React. 92 00:05:10,180 --> 00:05:13,290 And it's a pretty simple file that just implements a single function. 93 00:05:13,290 --> 00:05:16,960 This is a class that implements this function called render. 94 00:05:16,960 --> 00:05:20,980 And render is the most important function in React. 95 00:05:20,980 --> 00:05:26,360 The idea is instead of saying, OK, draw the screen. 96 00:05:26,360 --> 00:05:29,260 And then if you want something to change, you go in there 97 00:05:29,260 --> 00:05:31,900 and say, change it in an imperative way. 98 00:05:31,900 --> 00:05:35,810 What React does is it tells you to implement 99 00:05:35,810 --> 00:05:38,240 this render function that knows how to paint things 100 00:05:38,240 --> 00:05:41,240 to the screen at all times. 101 00:05:41,240 --> 00:05:44,360 And you can never really go in and change something explicitly, 102 00:05:44,360 --> 00:05:49,100 or say like, what we just did here where we changed this React into Hello World. 103 00:05:49,100 --> 00:05:50,420 You can never do that. 104 00:05:50,420 --> 00:05:54,551 The only thing you can do is call render. 105 00:05:54,551 --> 00:05:55,800 And that's really interesting. 106 00:05:55,800 --> 00:05:59,500 So the idea is that instead of going in and changing 107 00:05:59,500 --> 00:06:02,350 just a little piece of the screen, you have to rerender 108 00:06:02,350 --> 00:06:05,500 the whole thing every single time. 109 00:06:05,500 --> 00:06:08,660 The history of this is kind of interesting. 110 00:06:08,660 --> 00:06:11,870 It might not look very compelling at first, because you might be thinking, 111 00:06:11,870 --> 00:06:16,090 OK, if I'm rerendering the whole screen, this sounds kind of inefficient. 112 00:06:16,090 --> 00:06:18,940 Because I could just go in and just change that one little Hello 113 00:06:18,940 --> 00:06:19,902 World there. 114 00:06:19,902 --> 00:06:23,110 And that's a lot more efficient, because I don't have to rerender everything. 115 00:06:23,110 --> 00:06:23,860 Sure, that's true. 116 00:06:23,860 --> 00:06:27,190 But React can do some interesting tricks behind the scenes 117 00:06:27,190 --> 00:06:29,350 to make that faster for you. 118 00:06:29,350 --> 00:06:32,890 But the idea is that, although it might not sound very compelling at first, 119 00:06:32,890 --> 00:06:37,360 for really complicated apps, it is very compelling. 120 00:06:37,360 --> 00:06:42,160 Kind of story of this is related to a lot of game development. 121 00:06:42,160 --> 00:06:45,090 In games, you have a lot of stuff going on. 122 00:06:45,090 --> 00:06:46,690 So there's a character on the screen. 123 00:06:46,690 --> 00:06:49,570 The character is moving around, and there is stuff happening. 124 00:06:49,570 --> 00:06:50,470 There's wind coming. 125 00:06:50,470 --> 00:06:51,490 There's leaves falling. 126 00:06:51,490 --> 00:06:53,090 There's enemies all around. 127 00:06:53,090 --> 00:06:55,190 This is very, very complicated. 128 00:06:55,190 --> 00:06:58,330 And if you try to do things in this mutational way, where 129 00:06:58,330 --> 00:07:00,640 you say, for example, well, when you hit spacebar, 130 00:07:00,640 --> 00:07:02,320 the character's going to jump. 131 00:07:02,320 --> 00:07:05,470 OK, so let's go in and make the character jump. 132 00:07:05,470 --> 00:07:07,540 But when the character jumps, something can 133 00:07:07,540 --> 00:07:11,227 happen to the enemy that makes the enemy go to the right, for example, 134 00:07:11,227 --> 00:07:13,060 because you hit them or something like that. 135 00:07:13,060 --> 00:07:15,310 So one event will trigger the other event. 136 00:07:15,310 --> 00:07:17,830 So you get, OK, the character jumped. 137 00:07:17,830 --> 00:07:21,700 Now go in and mutate the enemy to make it go a little bit to the right. 138 00:07:21,700 --> 00:07:24,300 But the enemy going to the right can trigger another mutation 139 00:07:24,300 --> 00:07:27,520 that's going to make something else on the screen go to a different place. 140 00:07:27,520 --> 00:07:31,420 So you have these cascading effects of one event triggering the other event, 141 00:07:31,420 --> 00:07:32,830 triggering the other event. 142 00:07:32,830 --> 00:07:34,930 It might seem reasonable at first, but if you 143 00:07:34,930 --> 00:07:39,880 have a very complicated app like a video game with a lot of graphics going on, 144 00:07:39,880 --> 00:07:42,790 all these cascading events from the point of view of a developer 145 00:07:42,790 --> 00:07:45,610 might become completely impossible to work with. 146 00:07:45,610 --> 00:07:47,800 Because you might find an event happening 147 00:07:47,800 --> 00:07:50,279 that you have no idea why it happened, what's going on, 148 00:07:50,279 --> 00:07:53,320 and why the character just became blue and lost his head all of a sudden, 149 00:07:53,320 --> 00:07:56,980 because one little leaf on the left side of the screen 150 00:07:56,980 --> 00:08:01,150 just triggered a huge waterfall of events like this. 151 00:08:01,150 --> 00:08:04,210 So the way that the game developers deal with this is that they say, 152 00:08:04,210 --> 00:08:09,504 OK, let's have this abstract world that doesn't have anything 153 00:08:09,504 --> 00:08:10,420 to do with the screen. 154 00:08:10,420 --> 00:08:12,253 So we don't worry about painting the screen. 155 00:08:12,253 --> 00:08:16,190 So we just have these abstract concepts like the character position-- 156 00:08:16,190 --> 00:08:18,550 two numbers, x and y. 157 00:08:18,550 --> 00:08:22,390 The enemy positions-- so you might have an array that has a bunch of x and ys 158 00:08:22,390 --> 00:08:24,709 as well. 159 00:08:24,709 --> 00:08:27,000 You might have, for example, the direction of the wind. 160 00:08:27,000 --> 00:08:31,840 So this is kind of like just abstract numbers, just 161 00:08:31,840 --> 00:08:33,340 an abstract notion of everything. 162 00:08:33,340 --> 00:08:34,990 In React, we call this state. 163 00:08:34,990 --> 00:08:38,340 So we have this state, and then you have this function, 164 00:08:38,340 --> 00:08:43,080 which in React is going to call render which knows how to get a state 165 00:08:43,080 --> 00:08:44,940 and paint it to the screen. 166 00:08:44,940 --> 00:08:47,827 And that's all basically React is. 167 00:08:47,827 --> 00:08:50,160 That's basically the way that people in game development 168 00:08:50,160 --> 00:08:53,650 have solved these problems for many years now. 169 00:08:53,650 --> 00:08:58,660 And the idea is that if you want your character to jump, you don't say, hey, 170 00:08:58,660 --> 00:09:03,499 your Pixel right there, move a little bit to the right. 171 00:09:03,499 --> 00:09:04,290 You don't say that. 172 00:09:04,290 --> 00:09:08,960 What you do is you just change the state, and then you recall render. 173 00:09:08,960 --> 00:09:09,960 So you change the state. 174 00:09:09,960 --> 00:09:14,580 You say, like, position x is now 50, and you recall render. 175 00:09:14,580 --> 00:09:16,680 And render just rerenders the whole screen. 176 00:09:16,680 --> 00:09:18,690 But then it's smart, so it takes a difference 177 00:09:18,690 --> 00:09:21,210 between what was the last screen and what is the new screen. 178 00:09:21,210 --> 00:09:24,480 And then using this difference, it just updates up correct pixels. 179 00:09:24,480 --> 00:09:29,760 This is a lot more sane because now you can't have one event triggering 180 00:09:29,760 --> 00:09:32,600 the other, because you're not listening anymore 181 00:09:32,600 --> 00:09:34,230 to things happening on the screen. 182 00:09:34,230 --> 00:09:37,639 So, like, oh, one jump made some other thing happen. 183 00:09:37,639 --> 00:09:39,180 This is not what's happening anymore. 184 00:09:39,180 --> 00:09:42,510 You just do this data mutation-- the abstract data mutation-- 185 00:09:42,510 --> 00:09:47,640 and then you get essentially a painting from that. 186 00:09:47,640 --> 00:09:50,400 It is really important for this reason that this render function, 187 00:09:50,400 --> 00:09:53,850 both in React and in this game example that we just went over, 188 00:09:53,850 --> 00:09:57,630 is what we computer scientists call pure. 189 00:09:57,630 --> 00:10:01,320 Because the idea of pure is essentially that every time you 190 00:10:01,320 --> 00:10:03,840 call render with the same arguments, with the same state, 191 00:10:03,840 --> 00:10:06,250 it outputs the exact same thing. 192 00:10:06,250 --> 00:10:10,400 So render cannot have a thing that changes its own state in the middle 193 00:10:10,400 --> 00:10:10,900 of it. 194 00:10:10,900 --> 00:10:13,025 And that's really, really important, because if you 195 00:10:13,025 --> 00:10:16,290 have changing a variable-- 196 00:10:16,290 --> 00:10:22,510 let's say that this render in this case, it takes some state. 197 00:10:22,510 --> 00:10:25,780 And I'm going to add this here, so you guys understand. 198 00:10:25,780 --> 00:10:28,800 So this is a little bit of JavaScript syntax 199 00:10:28,800 --> 00:10:31,380 where I'm going to initialize some state. 200 00:10:31,380 --> 00:10:43,195 I'm going to say this dot state equals name equals David. 201 00:10:43,195 --> 00:10:45,690 And now, anywhere in your render function, 202 00:10:45,690 --> 00:10:47,320 you can actually refer to this state. 203 00:10:47,320 --> 00:10:50,260 Again, this is the same analogy as like your character position. 204 00:10:50,260 --> 00:10:53,553 And you can say in a new paragraph. 205 00:10:53,553 --> 00:10:57,980 206 00:10:57,980 --> 00:11:01,220 You can just open curly braces to go into JavaScript mode, 207 00:11:01,220 --> 00:11:03,601 and say, this dot state dot name. 208 00:11:03,601 --> 00:11:05,600 This is going to refer to that variable for you. 209 00:11:05,600 --> 00:11:08,900 And after we actually open or app, which we probably 210 00:11:08,900 --> 00:11:12,090 should have done already, with NPM start, 211 00:11:12,090 --> 00:11:13,590 this is going to run our dev server. 212 00:11:13,590 --> 00:11:16,180 213 00:11:16,180 --> 00:11:21,320 This is our simplest of React apps. 214 00:11:21,320 --> 00:11:23,939 That is not allowed before super. 215 00:11:23,939 --> 00:11:25,230 This is more JavaScript syntax. 216 00:11:25,230 --> 00:11:29,860 I have to call super in the constructor. 217 00:11:29,860 --> 00:11:31,910 There you go. 218 00:11:31,910 --> 00:11:37,920 And I didn't say Hello in here, so let's do a Hello, David. 219 00:11:37,920 --> 00:11:42,300 So this is probably one of the simplest React examples. 220 00:11:42,300 --> 00:11:44,430 It has this Welcome to React idea. 221 00:11:44,430 --> 00:11:49,460 And it does Hello, David in here with this state. 222 00:11:49,460 --> 00:11:56,290 And the idea is, again, if I change this state to be Hello, Gabriel, render 223 00:11:56,290 --> 00:11:57,830 didn't change. 224 00:11:57,830 --> 00:12:01,500 But render knows how to take a state and paint it on the screen. 225 00:12:01,500 --> 00:12:04,740 So it's going to paint it on the screen as Hello, Gabriel. 226 00:12:04,740 --> 00:12:06,882 And now, if any event happens-- 227 00:12:06,882 --> 00:12:07,840 let's start doing that. 228 00:12:07,840 --> 00:12:10,960 Let's say there is a button. 229 00:12:10,960 --> 00:12:19,021 Button Click me. 230 00:12:19,021 --> 00:12:21,350 Let's see if our button exists here. 231 00:12:21,350 --> 00:12:21,920 It does. 232 00:12:21,920 --> 00:12:23,220 It doesn't do anything yet. 233 00:12:23,220 --> 00:12:25,020 Let's make it do something. 234 00:12:25,020 --> 00:12:29,000 I'm going to attach an on Click Handler to this button. 235 00:12:29,000 --> 00:12:39,770 This dot [? onClickMe. ?] And in JavaScript, for reasons, I 236 00:12:39,770 --> 00:12:43,850 have to do this dot bind this, so I can access the this variable inside 237 00:12:43,850 --> 00:12:45,109 of the unClick me function. 238 00:12:45,109 --> 00:12:47,150 I'm going to define the [? onClickMe ?] function. 239 00:12:47,150 --> 00:12:49,940 240 00:12:49,940 --> 00:12:53,150 And what this function is going to do is just change the state. 241 00:12:53,150 --> 00:12:54,010 So again, same idea. 242 00:12:54,010 --> 00:12:57,940 If the character press spacebar, you don't change what's on the screen. 243 00:12:57,940 --> 00:12:59,894 You just change the position, and then render 244 00:12:59,894 --> 00:13:01,810 takes care of updating the data on the screen. 245 00:13:01,810 --> 00:13:13,062 So you say, this dot set state name to be Cats. 246 00:13:13,062 --> 00:13:17,910 247 00:13:17,910 --> 00:13:20,430 So now this says, Hello, Gabriel. 248 00:13:20,430 --> 00:13:23,900 If you click me, it also says, Hello, Cats. 249 00:13:23,900 --> 00:13:26,280 You just literally changed the state, and then it 250 00:13:26,280 --> 00:13:31,490 takes care of calling render for you and doing all the rest. 251 00:13:31,490 --> 00:13:33,870 And that's basically all there is to React. 252 00:13:33,870 --> 00:13:38,540 This is the core idea of everything that you need 253 00:13:38,540 --> 00:13:40,377 to know to get going with a React app. 254 00:13:40,377 --> 00:13:41,210 You have some state. 255 00:13:41,210 --> 00:13:43,940 You have a function that's special called render. 256 00:13:43,940 --> 00:13:47,240 It knows how to take a state and paint it on the screen. 257 00:13:47,240 --> 00:13:53,710 And event handlers, like this unClick right here, can mutate the state. 258 00:13:53,710 --> 00:13:57,670 Note again, take a moment to notice the difference between mutating the state 259 00:13:57,670 --> 00:14:01,600 and actually doing that get element by ID, 260 00:14:01,600 --> 00:14:04,640 imperatively setting the inner HTML to Cats. 261 00:14:04,640 --> 00:14:09,130 You would, in this case, achieve the exact same end goal, 262 00:14:09,130 --> 00:14:10,000 but it is different. 263 00:14:10,000 --> 00:14:12,070 Because there is this state step, and then 264 00:14:12,070 --> 00:14:15,280 calling the render function, which for much more complicated apps, 265 00:14:15,280 --> 00:14:18,370 is a really, really big deal. 266 00:14:18,370 --> 00:14:20,290 And basically, you can actually now go on 267 00:14:20,290 --> 00:14:24,680 and start just writing your React apps, which is really cool. 268 00:14:24,680 --> 00:14:28,600 This, by the way right here, is what we call JSX. 269 00:14:28,600 --> 00:14:32,950 It's essentially an embedding of HTML in CSS. 270 00:14:32,950 --> 00:14:36,970 Very similar-- the HTML is not quite HTML, but it's very close-- 271 00:14:36,970 --> 00:14:38,470 inside of JavaScript code. 272 00:14:38,470 --> 00:14:44,890 So the reason we can return this bunch of HTML inside of some JavaScript code 273 00:14:44,890 --> 00:14:47,830 is because of this language called JSX that eventually 274 00:14:47,830 --> 00:14:49,500 gets compiled all down to JavaScript. 275 00:14:49,500 --> 00:14:53,520 And that's also part of React tool chain. 276 00:14:53,520 --> 00:14:55,030 And this is all there is to React. 277 00:14:55,030 --> 00:14:56,440 So again, you have some state. 278 00:14:56,440 --> 00:14:58,780 You can mutate it when events happen, and then 279 00:14:58,780 --> 00:15:01,030 render those sort of paintings on the screen. 280 00:15:01,030 --> 00:15:06,280 Now where Pagedraw comes in is essentially takes over 281 00:15:06,280 --> 00:15:08,680 this render function for you. 282 00:15:08,680 --> 00:15:14,410 So Pagedraw automates a way for a lot of frontend development, 283 00:15:14,410 --> 00:15:18,310 but only kind of the dumb parts of frontend development. 284 00:15:18,310 --> 00:15:21,130 We do not want to take care of any of this unClick 285 00:15:21,130 --> 00:15:24,460 me logic, because this could be much more complicated than just 286 00:15:24,460 --> 00:15:26,110 setting a state to a different name. 287 00:15:26,110 --> 00:15:28,150 This cold be arbitrarily complicated. 288 00:15:28,150 --> 00:15:30,400 What we do is we just take care of the HTML 289 00:15:30,400 --> 00:15:34,990 and the CSS part for you, which lives inside of your render function. 290 00:15:34,990 --> 00:15:38,950 So in order to do something with Pagedraw, what I will do here 291 00:15:38,950 --> 00:15:43,920 is first, let's open up our Pagedraw doc, which is right here. 292 00:15:43,920 --> 00:15:45,670 And again, if you want to follow this, you 293 00:15:45,670 --> 00:15:49,420 can just go to documentation.pagedraw.io, 294 00:15:49,420 --> 00:15:51,670 and click on our tutorial, which will have everything 295 00:15:51,670 --> 00:15:53,450 that I'm showing you today. 296 00:15:53,450 --> 00:15:57,600 And this is our interface, our editor. 297 00:15:57,600 --> 00:16:00,810 You can hit R to draw rectangles. 298 00:16:00,810 --> 00:16:02,640 You can hit A to draw art boards. 299 00:16:02,640 --> 00:16:05,280 Ar boards are, for us, equivalent to Pagedraw components. 300 00:16:05,280 --> 00:16:08,760 So every time you draw an art board, you get React components. 301 00:16:08,760 --> 00:16:11,400 And the cool thing is that you can click on Export code, 302 00:16:11,400 --> 00:16:14,730 and we automatically export code for this one component for you. 303 00:16:14,730 --> 00:16:16,875 This is GSX again, and this is CSS. 304 00:16:16,875 --> 00:16:21,340 305 00:16:21,340 --> 00:16:27,550 I already have a sketch file that a designer in our team made earlier. 306 00:16:27,550 --> 00:16:30,610 If you don't use Sketch, you can just literally draw in here. 307 00:16:30,610 --> 00:16:33,640 Or if you are a designer, and you like using Sketch already, 308 00:16:33,640 --> 00:16:37,900 you can just import it like I'm about to do. 309 00:16:37,900 --> 00:16:42,130 So today, we're going to build a movie app. 310 00:16:42,130 --> 00:16:44,850 This is importing. 311 00:16:44,850 --> 00:16:46,880 Takes a second, but there it is. 312 00:16:46,880 --> 00:16:47,610 Cool. 313 00:16:47,610 --> 00:16:51,690 So I had a designer do this in Sketch where they just literally drew. 314 00:16:51,690 --> 00:16:54,840 Let me open up sketch, so you guys can see. 315 00:16:54,840 --> 00:17:01,700 Literally just drew this idea of an app for movies, called Movie Time. 316 00:17:01,700 --> 00:17:03,710 Again. there's nothing dynamic about it. 317 00:17:03,710 --> 00:17:05,000 There's no code here. 318 00:17:05,000 --> 00:17:06,980 This is just a static drawing. 319 00:17:06,980 --> 00:17:09,530 It's like you went to Photoshop, or Sketch in this case, 320 00:17:09,530 --> 00:17:11,694 and you just draw lines and text. 321 00:17:11,694 --> 00:17:13,819 Now we're going to do what we call productionizing. 322 00:17:13,819 --> 00:17:16,030 We're going to bring this into production using Pagedraw, 323 00:17:16,030 --> 00:17:18,170 and I'm going to show you how to make this app come 324 00:17:18,170 --> 00:17:22,130 to life while using Pagedraw to implement your react render 325 00:17:22,130 --> 00:17:24,680 functions for you. 326 00:17:24,680 --> 00:17:32,510 Before we dive in, you can check out what the final version looks like. 327 00:17:32,510 --> 00:17:35,840 There's a movie here, Monty Python and the Holy Grail, one of my favorites. 328 00:17:35,840 --> 00:17:38,570 You can write comments about the movie. 329 00:17:38,570 --> 00:17:41,720 Hi, I love this movie. 330 00:17:41,720 --> 00:17:42,290 Great. 331 00:17:42,290 --> 00:17:45,250 And you can choose a rating for it. 332 00:17:45,250 --> 00:17:48,850 So this is just to showcase some of Pagedraw plus React capabilities, 333 00:17:48,850 --> 00:17:53,680 so you're, hopefully, well-equipped to create something like this yourself. 334 00:17:53,680 --> 00:17:55,894 And if you click on the movie, it changes 335 00:17:55,894 --> 00:17:57,310 to another of my favorite movies-- 336 00:17:57,310 --> 00:17:58,490 Back to the Future. 337 00:17:58,490 --> 00:18:05,220 So this is the app we're going to build today, so let's get started. 338 00:18:05,220 --> 00:18:08,340 Now I just imported the Sketch file. 339 00:18:08,340 --> 00:18:12,000 But again, as I said, it does not have any dynamic data. 340 00:18:12,000 --> 00:18:15,104 So the first step that I'm going to do is I'm going to hit D for dynamic. 341 00:18:15,104 --> 00:18:17,770 And I'm going to click on everything that should be dynamic that 342 00:18:17,770 --> 00:18:19,228 should be coming from the database. 343 00:18:19,228 --> 00:18:21,830 For example, Pulp Fiction here should be dynamic. 344 00:18:21,830 --> 00:18:24,290 1994 also should be dynamic. 345 00:18:24,290 --> 00:18:27,530 And this text is a description should be dynamic. 346 00:18:27,530 --> 00:18:29,510 The director name should be dynamic. 347 00:18:29,510 --> 00:18:31,970 This comment should probably be dynamic too. 348 00:18:31,970 --> 00:18:35,450 And the image are the first things that I see that are dynamic. 349 00:18:35,450 --> 00:18:38,950 These stars are also dynamic, but I'll get to them later. 350 00:18:38,950 --> 00:18:41,040 OK, cool. 351 00:18:41,040 --> 00:18:44,300 Now what did I just do? 352 00:18:44,300 --> 00:18:47,980 I essentially said that these things are coming from some JavaScript. 353 00:18:47,980 --> 00:18:53,410 In Pagedraw, if I go to the code tab, and I click anywhere inside 354 00:18:53,410 --> 00:18:57,160 of this component to select it, the code tab's 355 00:18:57,160 --> 00:19:00,390 going to have a bunch of object inputs which are essentially 356 00:19:00,390 --> 00:19:04,240 variables, which are your state that we automatically define for you. 357 00:19:04,240 --> 00:19:08,550 They're all run of type string, except this one, which is of type image. 358 00:19:08,550 --> 00:19:11,250 And they have these names that are pretty standard default names 359 00:19:11,250 --> 00:19:16,080 that we created for you, called text, text 2, text 3, text 4. 360 00:19:16,080 --> 00:19:19,630 Again, because in Pagedraw this is a React component, 361 00:19:19,630 --> 00:19:24,420 this specifies what inputs, what state, that component's in. 362 00:19:24,420 --> 00:19:28,350 And here is where are they used. 363 00:19:28,350 --> 00:19:30,630 So if I click on this text input here, it 364 00:19:30,630 --> 00:19:38,040 says that, this dot props dot image source is going to be this image. 365 00:19:38,040 --> 00:19:43,740 Props is a thing that definitely deserves a word. 366 00:19:43,740 --> 00:19:44,520 In React. 367 00:19:44,520 --> 00:19:45,630 I just talked about state. 368 00:19:45,630 --> 00:19:51,705 It turns out that there is a different thing called props that it turns out, 369 00:19:51,705 --> 00:19:53,080 you can have multiple components. 370 00:19:53,080 --> 00:19:55,720 So if you have like a component 2 in React, 371 00:19:55,720 --> 00:19:58,750 you can actually use that inside of our render functions, 372 00:19:58,750 --> 00:20:02,490 and do something like component 2. 373 00:20:02,490 --> 00:20:05,950 The way to pass down variables from component 1 to component 2 374 00:20:05,950 --> 00:20:07,320 is through props. 375 00:20:07,320 --> 00:20:10,500 So you can pass a variable called foo equals 376 00:20:10,500 --> 00:20:14,550 this dot state dot name, for example. 377 00:20:14,550 --> 00:20:17,130 And inside of the render function of component 2, 378 00:20:17,130 --> 00:20:21,850 you're going to be able to refer to this foo variable. 379 00:20:21,850 --> 00:20:26,470 So let's actually do the definition here, so you guys understand. 380 00:20:26,470 --> 00:20:32,540 Class app, class component 2 extends component. 381 00:20:32,540 --> 00:20:36,130 I'll just define a very simple render function 382 00:20:36,130 --> 00:20:51,150 that just does this dot props dot foo. 383 00:20:51,150 --> 00:20:54,720 And instead of passing this as state dot name, 384 00:20:54,720 --> 00:20:56,560 I can pass whatever JavaScript I want here. 385 00:20:56,560 --> 00:21:01,345 So I'm going to do Hello plus CS 50. 386 00:21:01,345 --> 00:21:04,420 387 00:21:04,420 --> 00:21:08,470 So again, just showcasing the idea of props. 388 00:21:08,470 --> 00:21:09,977 Hello, CS50 is appearing here. 389 00:21:09,977 --> 00:21:11,310 We're using multiple components. 390 00:21:11,310 --> 00:21:13,090 So this idea of props is essentially state 391 00:21:13,090 --> 00:21:14,882 that you can pass down to other components. 392 00:21:14,882 --> 00:21:17,215 You don't really need, strictly speaking, two components 393 00:21:17,215 --> 00:21:18,020 or more components. 394 00:21:18,020 --> 00:21:22,742 But in order to make your app easier and more usable and more sane to work with, 395 00:21:22,742 --> 00:21:24,700 you probably want to separate those components, 396 00:21:24,700 --> 00:21:27,824 or even put some in different files, different folders, how every you want. 397 00:21:27,824 --> 00:21:30,640 React is not too opinionated about what you do with your components 398 00:21:30,640 --> 00:21:32,090 or where you should place them. 399 00:21:32,090 --> 00:21:35,080 It's kind of very up to you, which is really cool. 400 00:21:35,080 --> 00:21:40,030 All that React is doing is this state to render painting idea. 401 00:21:40,030 --> 00:21:42,610 And all of the rest is up to you, and it's just JavaScript, 402 00:21:42,610 --> 00:21:44,500 which I particularly really like. 403 00:21:44,500 --> 00:21:47,650 OK, now that you know what props are, let's go back 404 00:21:47,650 --> 00:21:50,080 and see what Pagedraw did there for us. 405 00:21:50,080 --> 00:21:54,580 So it defined that this component takes in a bunch of props. 406 00:21:54,580 --> 00:21:56,500 These are the types, and these are the names. 407 00:21:56,500 --> 00:22:00,820 And then he uses these props in all of the particular things that we clicked. 408 00:22:00,820 --> 00:22:04,480 So text 4 is the director here. 409 00:22:04,480 --> 00:22:07,930 And I'd actually already go ahead and change some of these names 410 00:22:07,930 --> 00:22:10,840 to become more sane. 411 00:22:10,840 --> 00:22:13,210 So text 4 is going to be just director. 412 00:22:13,210 --> 00:22:16,830 And I'm making these up right now. 413 00:22:16,830 --> 00:22:27,085 This guy's the movie title, which was just text movie title. 414 00:22:27,085 --> 00:22:30,570 415 00:22:30,570 --> 00:22:33,110 Text 2 is the movie year. 416 00:22:33,110 --> 00:22:38,190 417 00:22:38,190 --> 00:22:46,900 Text 5 is interesting, because this, I actually want to make it a list. 418 00:22:46,900 --> 00:22:49,790 So let's do that before. 419 00:22:49,790 --> 00:22:52,530 Because I want to have multiple comments here. 420 00:22:52,530 --> 00:22:58,501 So the way to do this is I can select both of the things 421 00:22:58,501 --> 00:22:59,750 that I wanted to go into list. 422 00:22:59,750 --> 00:23:03,500 This little line here and this text. 423 00:23:03,500 --> 00:23:04,549 And I can wrap it. 424 00:23:04,549 --> 00:23:06,840 This is just going to basically draw a block around it. 425 00:23:06,840 --> 00:23:08,840 So I can say that this block is going to repeat. 426 00:23:08,840 --> 00:23:12,100 And now I just click Repeat here, and bam, 427 00:23:12,100 --> 00:23:16,010 Pagedraw has created a list for me. 428 00:23:16,010 --> 00:23:19,260 Again, in the code sidebar, it says, this is a props dot list, 429 00:23:19,260 --> 00:23:21,950 and each item in the list is going to be called item. 430 00:23:21,950 --> 00:23:24,110 [INAUDIBLE] for now. 431 00:23:24,110 --> 00:23:27,270 Remember that, at all times, you can always export the code 432 00:23:27,270 --> 00:23:30,670 and see what we're doing there for you. 433 00:23:30,670 --> 00:23:34,870 So for example, here we're doing this dot props dot movie title. 434 00:23:34,870 --> 00:23:38,407 And the idea is you shouldn't really care about these class names and all 435 00:23:38,407 --> 00:23:38,990 of this stuff. 436 00:23:38,990 --> 00:23:41,040 This should be kind of like a black box to you, 437 00:23:41,040 --> 00:23:43,320 where you're just going to import this into Pagedraw. 438 00:23:43,320 --> 00:23:44,680 You'll see this very soon. 439 00:23:44,680 --> 00:23:47,782 But if you ever have a question about what Pagedraw is doing, 440 00:23:47,782 --> 00:23:49,740 you can just look at this and see, for example, 441 00:23:49,740 --> 00:23:51,115 this is a props dot list dot map. 442 00:23:51,115 --> 00:23:53,550 It's iterating over all of the list items, 443 00:23:53,550 --> 00:23:58,430 and calling each of them item, which means that in this-- 444 00:23:58,430 --> 00:24:00,380 I posted a comment about the movie-- 445 00:24:00,380 --> 00:24:07,580 instead of calling it text 5, I'm going to call it item dot content. 446 00:24:07,580 --> 00:24:10,050 Because inside of that scope, I have this item element 447 00:24:10,050 --> 00:24:12,040 that was defined there for me. 448 00:24:12,040 --> 00:24:13,605 Again, nothing new here. 449 00:24:13,605 --> 00:24:17,420 I'm just doing this in a visual way in Pagedraw, wiring out those variables. 450 00:24:17,420 --> 00:24:20,490 451 00:24:20,490 --> 00:24:22,470 OK, this is item dot content. 452 00:24:22,470 --> 00:24:26,940 That means I'm going to have to change my object input a little bit, 453 00:24:26,940 --> 00:24:29,330 because it's not just a string anymore. 454 00:24:29,330 --> 00:24:32,237 455 00:24:32,237 --> 00:24:34,320 There is this list called this dot props dot list. 456 00:24:34,320 --> 00:24:35,520 And I have to define it. 457 00:24:35,520 --> 00:24:38,217 Let's actually call it reviews. 458 00:24:38,217 --> 00:24:40,800 This dot props dot reviews is going to be the name of my list. 459 00:24:40,800 --> 00:24:43,320 So I'm going to add a new object input type. 460 00:24:43,320 --> 00:24:46,380 I'll call it reviews. 461 00:24:46,380 --> 00:24:49,590 I'm going to find its type to be list. 462 00:24:49,590 --> 00:24:52,680 And it's a list of objects. 463 00:24:52,680 --> 00:24:57,390 Each object has one content, which is a string. 464 00:24:57,390 --> 00:25:02,970 You can define any type of JavaScript object using this here. 465 00:25:02,970 --> 00:25:06,090 Now we're almost done naming our variables. 466 00:25:06,090 --> 00:25:12,890 Text 3 is the description, so I'm going to call this movie description. 467 00:25:12,890 --> 00:25:15,956 Text 3-- movie description. 468 00:25:15,956 --> 00:25:18,790 469 00:25:18,790 --> 00:25:20,800 So now I have this text, text 5, which used 470 00:25:20,800 --> 00:25:23,050 to be this comment, so I don't really need it anymore. 471 00:25:23,050 --> 00:25:26,300 I'm just going to delete it, although it would be fine to leave it there. 472 00:25:26,300 --> 00:25:27,470 Very cool. 473 00:25:27,470 --> 00:25:30,530 So we're now just done defining all of our variables. 474 00:25:30,530 --> 00:25:35,271 One really cool thing that we can do now is you can click on the artboard. 475 00:25:35,271 --> 00:25:37,270 So again, the components-- select this guy here. 476 00:25:37,270 --> 00:25:40,780 You can also make sure you select the artboard by clicking on the title 477 00:25:40,780 --> 00:25:42,070 up here. 478 00:25:42,070 --> 00:25:46,080 And you can go into stress tester mode. 479 00:25:46,080 --> 00:25:48,370 So stress tester mode is essentially a mode 480 00:25:48,370 --> 00:25:50,980 that lets you stress test your designs. 481 00:25:50,980 --> 00:25:52,825 Stress testing means we're going to see how 482 00:25:52,825 --> 00:25:55,450 it looks like with different data, with different screen sizes, 483 00:25:55,450 --> 00:25:57,500 and all that cool stuff. 484 00:25:57,500 --> 00:26:01,210 So you see here, we've already generated some random data 485 00:26:01,210 --> 00:26:04,150 that we put inside of your design. 486 00:26:04,150 --> 00:26:05,830 May the force be with you. 487 00:26:05,830 --> 00:26:07,080 Yo, Adrian! 488 00:26:07,080 --> 00:26:10,150 It went into all the things that you marked as dynamic before. 489 00:26:10,150 --> 00:26:13,120 And if you click randomize data up here, we change it. 490 00:26:13,120 --> 00:26:15,520 And you can see what happens in a different design. 491 00:26:15,520 --> 00:26:20,310 You can also see how it will look like with different screen sizes. 492 00:26:20,310 --> 00:26:24,360 And you see that this probably does not look like what you would want. 493 00:26:24,360 --> 00:26:26,670 You'd probably want some resizing behavior. 494 00:26:26,670 --> 00:26:30,060 In Pagedraw, when you bring a design in or you draw something yourself, 495 00:26:30,060 --> 00:26:32,760 we don't do any responsive by default. You 496 00:26:32,760 --> 00:26:34,450 have to tell us what you want to do. 497 00:26:34,450 --> 00:26:37,120 So for example, if you want this left-hand side 498 00:26:37,120 --> 00:26:40,170 sidebar to expand all the way, you're going 499 00:26:40,170 --> 00:26:43,470 to have to tell us by clicking on it using 500 00:26:43,470 --> 00:26:45,916 these flexible checkboxes on the right. 501 00:26:45,916 --> 00:26:48,540 So you can specify, for example, that it has a flexible height. 502 00:26:48,540 --> 00:26:51,816 503 00:26:51,816 --> 00:26:53,190 Click on here, and, there you go. 504 00:26:53,190 --> 00:26:55,210 It expanded to the whole screen. 505 00:26:55,210 --> 00:26:57,600 You can do this also to margins and to width, 506 00:26:57,600 --> 00:27:00,137 but there is a very nice button up top called Infer 507 00:27:00,137 --> 00:27:03,470 constraints, where we try to just do our best to infer these constraints of you. 508 00:27:03,470 --> 00:27:07,217 So if you click Infer constraints, it just did something reasonable. 509 00:27:07,217 --> 00:27:09,300 The idea is that you click there, and if something 510 00:27:09,300 --> 00:27:12,010 doesn't look like what you want, you'd probably work around it. 511 00:27:12,010 --> 00:27:14,040 So now that we've inferred these constraints, 512 00:27:14,040 --> 00:27:17,490 you can resize and see if this is kind of what you like. 513 00:27:17,490 --> 00:27:19,882 It looks pretty reasonable. 514 00:27:19,882 --> 00:27:21,590 You could argue for something like, oh, I 515 00:27:21,590 --> 00:27:24,720 want this what did you think aligned with the right comment 516 00:27:24,720 --> 00:27:29,110 because in the original design, they were aligned. 517 00:27:29,110 --> 00:27:34,140 A way to do this is I can always wrap things in blocks 518 00:27:34,140 --> 00:27:35,590 to force them to go on together. 519 00:27:35,590 --> 00:27:39,130 So if I click wrap again, now I have a whole block here. 520 00:27:39,130 --> 00:27:44,400 And if I go back to stress tester mode and click here on the art board, 521 00:27:44,400 --> 00:27:50,030 now if I resize, they're forced to be aligned. 522 00:27:50,030 --> 00:27:51,770 Again, whatever you want in here. 523 00:27:51,770 --> 00:27:54,700 524 00:27:54,700 --> 00:27:58,030 There's a nuance here which is that this is not resizing width 525 00:27:58,030 --> 00:28:02,620 any more, even though if I click on this guy, it does say flexible width. 526 00:28:02,620 --> 00:28:04,840 Because that's what we inferred from before. 527 00:28:04,840 --> 00:28:10,820 Because the parent block takes precedence in terms of flexibility. 528 00:28:10,820 --> 00:28:13,411 So if this parent is not marked flexible and the children are, 529 00:28:13,411 --> 00:28:15,910 you're going to ignore what the children are doing actually. 530 00:28:15,910 --> 00:28:20,230 So if we want this to stretch, we want to mark both the child and the parent 531 00:28:20,230 --> 00:28:23,560 as flexible width, which infer constraints would automatically 532 00:28:23,560 --> 00:28:24,520 do for us again. 533 00:28:24,520 --> 00:28:25,650 Well, there you go. 534 00:28:25,650 --> 00:28:30,050 If I want something like this, I just mark that at flexible. 535 00:28:30,050 --> 00:28:32,525 Cool. 536 00:28:32,525 --> 00:28:35,010 Awesome. 537 00:28:35,010 --> 00:28:38,870 Now, let's actually wire this into our React codebase. 538 00:28:38,870 --> 00:28:41,730 OK, this is the part that's very important. 539 00:28:41,730 --> 00:28:45,410 The idea is, again, I can click Export code. 540 00:28:45,410 --> 00:28:49,060 And I can just copy, paste. 541 00:28:49,060 --> 00:28:51,220 But there is a smarter way. 542 00:28:51,220 --> 00:28:53,880 Because if I'm constantly altering my design, 543 00:28:53,880 --> 00:28:56,570 this copy pasting becomes very bothersome. 544 00:28:56,570 --> 00:28:59,430 So what I can do is I can check this button here, 545 00:28:59,430 --> 00:29:02,252 which says [? should ?] pull and sync from the CLI. 546 00:29:02,252 --> 00:29:05,110 It turns out, we have a Pagedraw command line interface. 547 00:29:05,110 --> 00:29:08,580 And if you'll look at our documentation, you can read all about it here. 548 00:29:08,580 --> 00:29:12,850 And you can just install it by doing npm install dash g Pagedraw CLI. 549 00:29:12,850 --> 00:29:18,470 I already have it installed, so I have to do a couple things. 550 00:29:18,470 --> 00:29:24,560 First one is I have to do create a Pagedraw dot JSON in my root directory. 551 00:29:24,560 --> 00:29:27,250 [INAUDIBLE] run next to the package JSON. 552 00:29:27,250 --> 00:29:29,970 And it just needs one entry. 553 00:29:29,970 --> 00:29:36,030 That one entry is called app, and it just says the name of the app that 554 00:29:36,030 --> 00:29:37,920 I'm working with-- the Pagedraw app-- 555 00:29:37,920 --> 00:29:40,350 so we know where to fetch files from. 556 00:29:40,350 --> 00:29:41,790 So the name of my app is up here. 557 00:29:41,790 --> 00:29:42,914 It's called Movie Tutorial. 558 00:29:42,914 --> 00:29:45,650 559 00:29:45,650 --> 00:29:51,720 [? Codes are wrong. ?] Co My app is called Movie Tutorial. 560 00:29:51,720 --> 00:29:57,140 Now that I have this file, I can just say, page draw pull. 561 00:29:57,140 --> 00:30:02,330 And it's going to download and place these desktop HD dot GSX 562 00:30:02,330 --> 00:30:06,680 and CSS all inside source slash Pagedraw, which is our default 563 00:30:06,680 --> 00:30:07,880 directory for placing files. 564 00:30:07,880 --> 00:30:11,520 You can override this by going to the editor and changing file paths. 565 00:30:11,520 --> 00:30:14,330 566 00:30:14,330 --> 00:30:16,220 This is just doing this pull once. 567 00:30:16,220 --> 00:30:20,480 If I wanted to constantly keep syncing, I can say, Pagedraw sync instead. 568 00:30:20,480 --> 00:30:23,300 And it's going to just keep listening for changes in the doc 569 00:30:23,300 --> 00:30:26,220 and keep constantly fetching them and putting them in my file system. 570 00:30:26,220 --> 00:30:28,447 So I just leave this Pagedraw sync here for now. 571 00:30:28,447 --> 00:30:29,780 So I have Pagedraw sync running. 572 00:30:29,780 --> 00:30:34,560 I have NPM start running, which is my local dev server. 573 00:30:34,560 --> 00:30:40,700 So now if we go into app dot js, we can actually 574 00:30:40,700 --> 00:30:46,380 get rid of all this render stuff because Pagedraw is going to do this for us. 575 00:30:46,380 --> 00:30:47,970 And get rid of component 2. 576 00:30:47,970 --> 00:30:49,260 I don't need anymore CSS. 577 00:30:49,260 --> 00:30:51,750 I don't need anymore logo images. 578 00:30:51,750 --> 00:30:54,060 And I can just import. 579 00:30:54,060 --> 00:30:55,260 I'll call this app render. 580 00:30:55,260 --> 00:30:57,720 I could call it banana if I wanted to. 581 00:30:57,720 --> 00:31:01,080 From dot splash Pagedraw slash. 582 00:31:01,080 --> 00:31:05,310 And again, the name of the file is desktop HD. 583 00:31:05,310 --> 00:31:07,990 Desktop HD. 584 00:31:07,990 --> 00:31:14,690 And now my render function becomes just one line, which is really cool. 585 00:31:14,690 --> 00:31:17,760 App render, return. 586 00:31:17,760 --> 00:31:21,790 587 00:31:21,790 --> 00:31:22,970 Awesome. 588 00:31:22,970 --> 00:31:27,550 So if I go here-- 589 00:31:27,550 --> 00:31:29,180 bam-- I'm getting errors. 590 00:31:29,180 --> 00:31:30,360 Where are these errors? 591 00:31:30,360 --> 00:31:36,350 Well, app did require the Pagedraw component correctly. 592 00:31:36,350 --> 00:31:37,670 It is returning as app render. 593 00:31:37,670 --> 00:31:38,270 Everything is correct. 594 00:31:38,270 --> 00:31:40,700 But remember that we defined all of those dynamic things, 595 00:31:40,700 --> 00:31:44,630 so this is trying to access this dot props reviews that we defined in there. 596 00:31:44,630 --> 00:31:48,600 But we're never passing down reviews into app render right here. 597 00:31:48,600 --> 00:31:57,700 So I can just say, reviews equals whatever. 598 00:31:57,700 --> 00:32:06,310 And, sorry, you need curly brace just like on mt list. 599 00:32:06,310 --> 00:32:07,330 So there we go. 600 00:32:07,330 --> 00:32:09,610 Now that we have reviews, we have zero comments. 601 00:32:09,610 --> 00:32:13,220 We have essentially undefined for everything else. 602 00:32:13,220 --> 00:32:16,540 So we are rendering the page, it just doesn't have any data yet. 603 00:32:16,540 --> 00:32:20,340 So I already have all this data actually in a different file. 604 00:32:20,340 --> 00:32:23,380 So I'm just going to bring it from there, because this part is not 605 00:32:23,380 --> 00:32:24,747 very interesting. 606 00:32:24,747 --> 00:32:33,880 607 00:32:33,880 --> 00:32:35,630 So this is just again doing the same thing 608 00:32:35,630 --> 00:32:38,890 we were doing before by creating some state with all those variables 609 00:32:38,890 --> 00:32:39,820 that we defined. 610 00:32:39,820 --> 00:32:42,130 And the idea with Pagedraw is that frontend development 611 00:32:42,130 --> 00:32:44,350 becomes a lot more like backend development, where 612 00:32:44,350 --> 00:32:47,060 my job as a developer is to deal with data, 613 00:32:47,060 --> 00:32:49,480 and not at all worry about whether something is blue 614 00:32:49,480 --> 00:32:52,063 or is in the middle of a screen or to the right of the screen. 615 00:32:52,063 --> 00:32:54,430 That should be black boxed away from me. 616 00:32:54,430 --> 00:32:55,562 I just deal with data. 617 00:32:55,562 --> 00:32:56,770 I fetch data from a database. 618 00:32:56,770 --> 00:32:57,730 I create data. 619 00:32:57,730 --> 00:33:00,610 And if some events happen, I change that data. 620 00:33:00,610 --> 00:33:03,090 And that's all my job as a developer should be, 621 00:33:03,090 --> 00:33:07,740 and Pagedraw takes care of doing essentially the painting part for you. 622 00:33:07,740 --> 00:33:12,255 So let's copy all of this in. 623 00:33:12,255 --> 00:33:13,970 I actually just need these guys. 624 00:33:13,970 --> 00:33:26,340 625 00:33:26,340 --> 00:33:27,420 This is title here. 626 00:33:27,420 --> 00:33:31,240 It's actually movie title that I want. 627 00:33:31,240 --> 00:33:34,342 And now I'm going to return to app render, which is pretty stupid. 628 00:33:34,342 --> 00:33:36,550 It's just like passing down all of these state things 629 00:33:36,550 --> 00:33:38,383 into the render function like we did before. 630 00:33:38,383 --> 00:33:43,560 631 00:33:43,560 --> 00:33:47,180 So this title image source, it has a few other things 632 00:33:47,180 --> 00:33:52,670 that I'm going to add later, like this comment being typed. 633 00:33:52,670 --> 00:33:54,360 I'm going to add all of these later. 634 00:33:54,360 --> 00:33:58,710 Let's just focus on the stuff that we have so far. 635 00:33:58,710 --> 00:34:03,800 App render, and I need to finish with backslash [INAUDIBLE] syntax. 636 00:34:03,800 --> 00:34:07,790 Reviews, movie, year, director. 637 00:34:07,790 --> 00:34:09,985 I call that actually Movie Title instead of title. 638 00:34:09,985 --> 00:34:15,889 639 00:34:15,889 --> 00:34:20,385 Now reviews doesn't exist. 640 00:34:20,385 --> 00:34:22,900 641 00:34:22,900 --> 00:34:24,860 Reviews is supposed to exist. 642 00:34:24,860 --> 00:34:27,585 Oh, yeah, I didn't bring the reviews. 643 00:34:27,585 --> 00:34:28,085 Reviews. 644 00:34:28,085 --> 00:34:33,296 645 00:34:33,296 --> 00:34:36,170 And again, reviews is a list of a bunch of objects with that content. 646 00:34:36,170 --> 00:34:41,080 647 00:34:41,080 --> 00:34:43,230 Now I just decided that actually I wanted the 648 00:34:43,230 --> 00:34:45,280 write a comment to not go down there. 649 00:34:45,280 --> 00:34:47,810 And probably this image is stretching in a weird way. 650 00:34:47,810 --> 00:34:49,310 So I can always go back to Pagedraw. 651 00:34:49,310 --> 00:34:51,851 And the cool thing now, because I have Pagedraw Sync running, 652 00:34:51,851 --> 00:34:56,050 is if I do some change where I decide, for example, that this big block 653 00:34:56,050 --> 00:34:59,920 doesn't exist anymore, and I want these two to be separated, I just delete it. 654 00:34:59,920 --> 00:35:03,190 And it should already refresh automatically, and there you go. 655 00:35:03,190 --> 00:35:05,620 But still my image looks a little bit funky here. 656 00:35:05,620 --> 00:35:10,300 So what I probably want is there is different ways of choosing 657 00:35:10,300 --> 00:35:12,800 how an image is going to fit the block. 658 00:35:12,800 --> 00:35:15,172 So instead of stretch, I'm going to say, contain, 659 00:35:15,172 --> 00:35:17,880 which I think in this case is going to be a little bit more sane. 660 00:35:17,880 --> 00:35:18,950 There you go. 661 00:35:18,950 --> 00:35:21,820 This looks better. 662 00:35:21,820 --> 00:35:25,620 OK, so we have an app that just knows how to paint things on the screen. 663 00:35:25,620 --> 00:35:27,240 And this is all done by Pagedraw. 664 00:35:27,240 --> 00:35:32,010 It's real cool if I want to change the color here, I just click here, 665 00:35:32,010 --> 00:35:38,650 and it's already going to reload and change there. 666 00:35:38,650 --> 00:35:39,440 Very cool. 667 00:35:39,440 --> 00:35:41,939 So the idea is that Pagedraw takes over our render function. 668 00:35:41,939 --> 00:35:46,406 Now our job is just to do some state mutations. 669 00:35:46,406 --> 00:35:49,030 The last part that we need to do is make this actually dynamic, 670 00:35:49,030 --> 00:35:50,680 where this comment thing. 671 00:35:50,680 --> 00:35:53,140 I can't really type here or add any comments yet. 672 00:35:53,140 --> 00:35:56,110 And I can't do the star functionality. 673 00:35:56,110 --> 00:35:59,980 So let's do the comment idea first. 674 00:35:59,980 --> 00:36:02,920 So in React, because everything is state, 675 00:36:02,920 --> 00:36:06,307 first we have to turn this into a text input, so the user can type. 676 00:36:06,307 --> 00:36:09,140 So right now, this is some text, because we imported it from Sketch. 677 00:36:09,140 --> 00:36:10,810 And this is just text there. 678 00:36:10,810 --> 00:36:16,900 So I'm going to change the block type into text input. 679 00:36:16,900 --> 00:36:19,750 And the placeholder's going to be your comment. 680 00:36:19,750 --> 00:36:21,510 And again, an unstyled text input. 681 00:36:21,510 --> 00:36:23,230 It just comes with some default styles. 682 00:36:23,230 --> 00:36:29,110 I'm going to say it has 0 border, and its fill color 683 00:36:29,110 --> 00:36:33,250 is completely transparent. 684 00:36:33,250 --> 00:36:38,650 And if I check in my Sketch file, I'm pretty sure that the size of the font 685 00:36:38,650 --> 00:36:41,320 was 18. 686 00:36:41,320 --> 00:36:42,580 Yep, 18. 687 00:36:42,580 --> 00:36:46,080 So I'm just going to type in 18 for the font size. 688 00:36:46,080 --> 00:36:50,962 689 00:36:50,962 --> 00:36:53,920 I would like that to be aligned to the left, just like the Sketch file, 690 00:36:53,920 --> 00:36:58,990 so you can actually click on, Use custom padding, and padding [INAUDIBLE] 0. 691 00:36:58,990 --> 00:37:00,390 There we go. 692 00:37:00,390 --> 00:37:02,080 Now this is an actual text input. 693 00:37:02,080 --> 00:37:08,070 If I go to my React app, I can type in here. 694 00:37:08,070 --> 00:37:10,170 Oh, the color is dark. 695 00:37:10,170 --> 00:37:13,540 I probably don't want that. 696 00:37:13,540 --> 00:37:18,426 Let's do something like white for the text color. 697 00:37:18,426 --> 00:37:20,130 Cool, that's what I want. 698 00:37:20,130 --> 00:37:22,230 But just typing here doesn't do anything yet. 699 00:37:22,230 --> 00:37:26,640 It doesn't really add anything to my reviews array, 700 00:37:26,640 --> 00:37:29,670 because we're not doing any state mutations. 701 00:37:29,670 --> 00:37:34,710 So the way that React does this is a little bit interesting 702 00:37:34,710 --> 00:37:36,460 and a little bit different for some people 703 00:37:36,460 --> 00:37:38,700 who are coming from an not React background. 704 00:37:38,700 --> 00:37:42,300 So the idea is right now, we're violating 705 00:37:42,300 --> 00:37:45,330 the React fundamental paradigm. 706 00:37:45,330 --> 00:37:46,770 Why is that? 707 00:37:46,770 --> 00:37:49,240 We are violating the React paradigm because you 708 00:37:49,240 --> 00:37:53,010 see that something is changing on the screen when I type here. 709 00:37:53,010 --> 00:37:56,010 But there is no state changing. 710 00:37:56,010 --> 00:38:01,710 And this is basically going against what React is. 711 00:38:01,710 --> 00:38:05,030 Because the idea is that, again, it should be a pure function. 712 00:38:05,030 --> 00:38:07,380 That every time you have the same state, you 713 00:38:07,380 --> 00:38:10,186 should get the exact same painting of the screen. 714 00:38:10,186 --> 00:38:11,560 But right now, we have one state. 715 00:38:11,560 --> 00:38:12,930 We didn't change that at all. 716 00:38:12,930 --> 00:38:18,030 And we have different paintings when I'm typing something here. 717 00:38:18,030 --> 00:38:22,150 So the first thing I have to do is I have to turn this into some state, 718 00:38:22,150 --> 00:38:26,190 so I can refer to it later to basically fetch this comment. 719 00:38:26,190 --> 00:38:30,890 So the way to do this is, well, I'm going to first, in my code, 720 00:38:30,890 --> 00:38:40,180 add some comment being typed state that starts as nothing, starts empty. 721 00:38:40,180 --> 00:38:43,940 And I'm going to pass it down to app render just like everything else. 722 00:38:43,940 --> 00:38:50,045 Comment being typed equals this dot state dot comment being typed. 723 00:38:50,045 --> 00:38:53,259 724 00:38:53,259 --> 00:38:55,050 And now I just have to use this in Pagedraw 725 00:38:55,050 --> 00:38:58,800 to say that that's what going to be the value in there. 726 00:38:58,800 --> 00:39:03,190 The way to do this is on the sidebar, in the same way 727 00:39:03,190 --> 00:39:06,220 we did D for dynamic earlier, I can actually 728 00:39:06,220 --> 00:39:09,446 hover over a bunch of these things, like placeholder, 729 00:39:09,446 --> 00:39:12,070 and I get this little icon right there that says, Make dynamic. 730 00:39:12,070 --> 00:39:14,770 So I can make anything in Pagedraw dynamic, 731 00:39:14,770 --> 00:39:17,950 like the font size, the font color, the background color, whatever you want. 732 00:39:17,950 --> 00:39:19,824 In this case, I want to make the value, which 733 00:39:19,824 --> 00:39:23,860 is the text that's going to be inside of this text input dynamic. 734 00:39:23,860 --> 00:39:28,540 As soon as I make something dynamic, and now if I go to the code sidebar, 735 00:39:28,540 --> 00:39:34,270 I actually get a new text input value that needs some variable to go in here. 736 00:39:34,270 --> 00:39:39,400 And be highlighted in red for you, so you know that it's empty. 737 00:39:39,400 --> 00:39:43,140 But now there's going to come from this dot state R this dot props [INAUDIBLE] 738 00:39:43,140 --> 00:39:48,590 dot comment being typed. 739 00:39:48,590 --> 00:39:54,086 If I reload my React app, and now if I try to type here-- 740 00:39:54,086 --> 00:39:55,090 oh, it's changing. 741 00:39:55,090 --> 00:39:56,380 It's shouldn't. 742 00:39:56,380 --> 00:39:57,170 Let's see. 743 00:39:57,170 --> 00:40:00,300 744 00:40:00,300 --> 00:40:03,840 So I'm trying to type here, it does not let me type. 745 00:40:03,840 --> 00:40:05,100 Why is this happening? 746 00:40:05,100 --> 00:40:09,480 Because now we're not breaking the React paradigm anymore because now 747 00:40:09,480 --> 00:40:13,350 we have a state that comes into the value of this text input. 748 00:40:13,350 --> 00:40:16,290 The state is comment being typed is empty. 749 00:40:16,290 --> 00:40:19,660 And never do I say comment being typed changes. 750 00:40:19,660 --> 00:40:22,740 So that's why you never see any comment here, 751 00:40:22,740 --> 00:40:25,440 which is kind of interesting and kind of unintuitive 752 00:40:25,440 --> 00:40:27,010 for people coming to React at first. 753 00:40:27,010 --> 00:40:28,343 This is a really powerful idea-- 754 00:40:28,343 --> 00:40:32,860 this idea of state should define completely what your screen looks like. 755 00:40:32,860 --> 00:40:38,050 So now I need to add an event handler that every time someone types 756 00:40:38,050 --> 00:40:43,710 a letter, say A, it should change comment being typed from nothing to A. 757 00:40:43,710 --> 00:40:46,170 The way to do this is in Pagedraw, you can 758 00:40:46,170 --> 00:40:50,550 click on any block to define event handlers as draw sidebar. 759 00:40:50,550 --> 00:40:53,790 At the end, you see this array here of event handlers? 760 00:40:53,790 --> 00:40:58,360 You can just click Plus, and say whatever event handler you want. 761 00:40:58,360 --> 00:41:00,402 And we just support all the React event handlers. 762 00:41:00,402 --> 00:41:03,109 You can go to React if you want to see all of the event handlers. 763 00:41:03,109 --> 00:41:05,950 They're basically wrappers on top of the browsers' event handlers. 764 00:41:05,950 --> 00:41:09,387 So instead of on click, I'm going to do actually on change. 765 00:41:09,387 --> 00:41:11,970 And here, I'll just say the name of the function that I want-- 766 00:41:11,970 --> 00:41:18,080 this dot props dot on change comment. 767 00:41:18,080 --> 00:41:20,240 I just chose the name of the function. 768 00:41:20,240 --> 00:41:22,220 So now let's actually implement this. 769 00:41:22,220 --> 00:41:24,720 I can get rid of the on click me that we were using earlier, 770 00:41:24,720 --> 00:41:29,250 and just say, on change comment. 771 00:41:29,250 --> 00:41:33,930 772 00:41:33,930 --> 00:41:38,760 And I'll actually just copy this from here, so I don't forget the syntax. 773 00:41:38,760 --> 00:41:41,946 774 00:41:41,946 --> 00:41:43,530 This is very simple. 775 00:41:43,530 --> 00:41:47,870 The idea is that every time there is an on change event happening, 776 00:41:47,870 --> 00:41:48,980 I get that event. 777 00:41:48,980 --> 00:41:50,720 I take its value. 778 00:41:50,720 --> 00:41:52,970 And I update using this [INAUDIBLE] state, the comment 779 00:41:52,970 --> 00:41:54,870 being typed to be that new value. 780 00:41:54,870 --> 00:41:56,150 And that's all it is. 781 00:41:56,150 --> 00:41:57,704 This is standard React, by the way. 782 00:41:57,704 --> 00:41:59,120 This is nothing Pagedraw specific. 783 00:41:59,120 --> 00:42:02,510 Pagedraw just allows you to attach these React event handlers to things. 784 00:42:02,510 --> 00:42:04,610 This is the exact same thing that you'd be doing 785 00:42:04,610 --> 00:42:06,800 if you were just using normal React. 786 00:42:06,800 --> 00:42:11,330 And again, the idea of Pagedraw is that Pagedraw does not 787 00:42:11,330 --> 00:42:14,810 change your React work flow basically. 788 00:42:14,810 --> 00:42:17,150 It just fits right into the render function. 789 00:42:17,150 --> 00:42:19,880 All the rest should look exactly like it would look like. 790 00:42:19,880 --> 00:42:22,610 Your backend, your event handlers, your state management 791 00:42:22,610 --> 00:42:28,160 should look exactly like without Pagedraw, but with React. 792 00:42:28,160 --> 00:42:30,769 That means we don't import any like weird libraries. 793 00:42:30,769 --> 00:42:33,560 We're just importing React here, which is really important to note. 794 00:42:33,560 --> 00:42:37,640 OK, on change comment then. 795 00:42:37,640 --> 00:42:40,550 Now we get back to where we were where if I type something-- 796 00:42:40,550 --> 00:42:41,675 I should probably refresh-- 797 00:42:41,675 --> 00:42:46,060 798 00:42:46,060 --> 00:42:49,720 oh, yeah, I never passed it down to the app render component. 799 00:42:49,720 --> 00:42:56,410 So on change comment equals this dot on change comment. 800 00:42:56,410 --> 00:43:00,506 And I have to do that weird bind this again, 801 00:43:00,506 --> 00:43:03,130 so I have access to the this keyword, instead of this function. 802 00:43:03,130 --> 00:43:05,870 803 00:43:05,870 --> 00:43:07,660 Now I can type again. 804 00:43:07,660 --> 00:43:11,670 But this time, it looks exactly the same as before. 805 00:43:11,670 --> 00:43:13,830 But every time I type something, we're actually 806 00:43:13,830 --> 00:43:16,459 updating the internal react state, which is a huge deal. 807 00:43:16,459 --> 00:43:18,500 Because now, we can actually access this this dot 808 00:43:18,500 --> 00:43:21,816 state dot comment being typed anywhere we want, 809 00:43:21,816 --> 00:43:23,190 which is what we want to do next. 810 00:43:23,190 --> 00:43:25,920 The idea is that whenever we click on this plus button here, 811 00:43:25,920 --> 00:43:29,910 we want to query what is the comment being typed and add it to this list. 812 00:43:29,910 --> 00:43:32,010 Let's just do that right now. 813 00:43:32,010 --> 00:43:37,750 I will first make this blue icon in Pagedraw have a cursor. 814 00:43:37,750 --> 00:43:40,750 So whenever someone hovers over it, it's going to be different, 815 00:43:40,750 --> 00:43:42,140 like a pointer thing. 816 00:43:42,140 --> 00:43:43,500 Let's see. 817 00:43:43,500 --> 00:43:44,790 There you go. 818 00:43:44,790 --> 00:43:46,320 That's just a style thing. 819 00:43:46,320 --> 00:43:48,300 And I'm going to attach an event handler. 820 00:43:48,300 --> 00:43:50,000 This time in on click. 821 00:43:50,000 --> 00:43:55,550 That does this dot props dot on add comment. 822 00:43:55,550 --> 00:43:59,410 And again, I'm making these up as I go. 823 00:43:59,410 --> 00:44:02,620 So add comment. 824 00:44:02,620 --> 00:44:04,680 I'm going to copy this in again. 825 00:44:04,680 --> 00:44:06,541 But it's pretty straightforward. 826 00:44:06,541 --> 00:44:09,190 827 00:44:09,190 --> 00:44:13,330 And it's on add comment is what I called it. 828 00:44:13,330 --> 00:44:15,670 And I'll pass it down to the component just 829 00:44:15,670 --> 00:44:23,926 like I did before. on add comment this dot on comments dot [? bind ?] this. 830 00:44:23,926 --> 00:44:26,360 This function is pretty straightforward. 831 00:44:26,360 --> 00:44:31,139 All it's doing is, it's updating the reviews, or state. 832 00:44:31,139 --> 00:44:34,180 And maybe if they have a real app, it should be like go into the database 833 00:44:34,180 --> 00:44:35,272 and changing that entry. 834 00:44:35,272 --> 00:44:37,480 The database right now, we just have things in memory 835 00:44:37,480 --> 00:44:40,840 and this big [INAUDIBLE] array, which is fine. 836 00:44:40,840 --> 00:44:48,130 And it's concatenating to the this dot state dot comment being typed into it. 837 00:44:48,130 --> 00:44:51,760 So it's getting these new reviews, and then it's setting the state of reviews 838 00:44:51,760 --> 00:44:53,630 to be new reviews. 839 00:44:53,630 --> 00:44:56,500 And it also sets the state of comment being typed to be nothing. 840 00:44:56,500 --> 00:45:00,730 If we don't do that, we would add it to the reviews list, 841 00:45:00,730 --> 00:45:03,950 but you wouldn't essentially erase what you 842 00:45:03,950 --> 00:45:07,750 were typing, which would be slightly awkward from a user perspective. 843 00:45:07,750 --> 00:45:17,620 So now if we go back to our app, you can type, Hello CS 50, and click, Plus. 844 00:45:17,620 --> 00:45:20,570 And I think I didn't refresh. 845 00:45:20,570 --> 00:45:23,930 Hello, CS 50. 846 00:45:23,930 --> 00:45:26,240 Something is happening. 847 00:45:26,240 --> 00:45:30,660 Want add comment on add comment. 848 00:45:30,660 --> 00:45:32,520 I have three Ms in comment. 849 00:45:32,520 --> 00:45:34,650 I think I just spotted the bug. 850 00:45:34,650 --> 00:45:36,430 Thank you very much, Dan. 851 00:45:36,430 --> 00:45:40,020 I think my problem from before is that I was passing on add comment 852 00:45:40,020 --> 00:45:42,910 with three Ms. That is totally my bad. 853 00:45:42,910 --> 00:45:47,310 OK, I think now things should be working hopefully. 854 00:45:47,310 --> 00:45:49,740 So now, let's first test the other one. 855 00:45:49,740 --> 00:45:50,730 Click here. 856 00:45:50,730 --> 00:45:51,990 There we go. 857 00:45:51,990 --> 00:45:53,400 Sweet. 858 00:45:53,400 --> 00:45:57,150 So now the props, if you get the names right-- 859 00:45:57,150 --> 00:46:00,600 which I didn't-- whenever you click on this, 860 00:46:00,600 --> 00:46:05,110 that function's going to be called which is going to set the state of a new 861 00:46:05,110 --> 00:46:07,560 reviews list, which is what we wanted. 862 00:46:07,560 --> 00:46:10,390 Hey, this is working. 863 00:46:10,390 --> 00:46:15,870 But now we just got two event handlers that are hopefully working. 864 00:46:15,870 --> 00:46:17,490 That was one. 865 00:46:17,490 --> 00:46:21,360 And if I now click on this guy, it changes the movie. 866 00:46:21,360 --> 00:46:23,400 I didn't change the title. 867 00:46:23,400 --> 00:46:27,220 It's still Monty Python because I'm setting the states to this title, 868 00:46:27,220 --> 00:46:29,945 but I actually used the name Movie Title in this example. 869 00:46:29,945 --> 00:46:31,570 So let's refresh, make sure that works. 870 00:46:31,570 --> 00:46:33,240 So click on that. 871 00:46:33,240 --> 00:46:35,730 It goes to another one of my favorite movies. 872 00:46:35,730 --> 00:46:38,940 And again, this is just attaching event handlers. 873 00:46:38,940 --> 00:46:43,650 And the event handlers are implemented outside of Pagedraw in good old React, 874 00:46:43,650 --> 00:46:45,750 which is just JavaScript. 875 00:46:45,750 --> 00:46:50,010 [INAUDIBLE] console dot log anymore. 876 00:46:50,010 --> 00:46:56,340 Now remember that I set an event handler here when I was debugging. 877 00:46:56,340 --> 00:46:57,730 I'm just going to delete that. 878 00:46:57,730 --> 00:47:01,860 I don't want that part to do on add comment anymore. 879 00:47:01,860 --> 00:47:05,760 And every time you're in a good state, let's say we're in a good state 880 00:47:05,760 --> 00:47:07,830 right now, we like this. 881 00:47:07,830 --> 00:47:09,030 You can commit. 882 00:47:09,030 --> 00:47:12,160 You see up here we say we have uncommitted changes. 883 00:47:12,160 --> 00:47:17,490 So if you select a doc by unselecting any block on the screen, 884 00:47:17,490 --> 00:47:19,470 you see all of my commits previously here. 885 00:47:19,470 --> 00:47:23,880 And I can say, good state for CS 50. 886 00:47:23,880 --> 00:47:25,770 Yay, Include commit. 887 00:47:25,770 --> 00:47:30,810 This way, if someone screws up your doc, changes something, oh, my god, I just 888 00:47:30,810 --> 00:47:31,950 lost everything. 889 00:47:31,950 --> 00:47:35,100 You can click, Restore, and it's going to go back to your good state. 890 00:47:35,100 --> 00:47:37,920 So we're happy about that. 891 00:47:37,920 --> 00:47:40,470 Another a little thing that just showed up and some people 892 00:47:40,470 --> 00:47:44,470 get confused by is if you have two blocks overlapping in Pagedraw, 893 00:47:44,470 --> 00:47:48,000 we show red lines, like that, to basically alert you 894 00:47:48,000 --> 00:47:52,270 that if you have overlapping blocks, we can do them if you want. 895 00:47:52,270 --> 00:47:55,140 We're just going to have to do position absolute in CSS, 896 00:47:55,140 --> 00:47:56,650 which might not be what you want. 897 00:47:56,650 --> 00:47:59,190 So we warn you to see if you really want that. 898 00:47:59,190 --> 00:48:03,204 And often, when you bring Sketch files in, if they're not super polished, 899 00:48:03,204 --> 00:48:04,620 they often come with these things. 900 00:48:04,620 --> 00:48:08,010 Because in Sketch, it doesn't really matter if you have things overlapping. 901 00:48:08,010 --> 00:48:11,890 So one of the steps is also to fix all of those overlapping things, 902 00:48:11,890 --> 00:48:15,230 just so you know to look for it in this. 903 00:48:15,230 --> 00:48:23,360 Now the last thing I want to do is implement this little star component 904 00:48:23,360 --> 00:48:24,300 widget right here. 905 00:48:24,300 --> 00:48:26,360 And again, I just want to have like a rating, 906 00:48:26,360 --> 00:48:28,920 and let the user select the rating. 907 00:48:28,920 --> 00:48:33,480 And notice that we have three states that the star can be in. 908 00:48:33,480 --> 00:48:37,310 Either this is a state of hovering-- the blue one-- this is a state of unfilled, 909 00:48:37,310 --> 00:48:38,640 and this is a state of filled. 910 00:48:38,640 --> 00:48:42,360 So in order to do this in Pagedraw, in order to do this in code, 911 00:48:42,360 --> 00:48:45,810 you do it with an if essentially, where you say, if this is filled, 912 00:48:45,810 --> 00:48:47,030 like do something here. 913 00:48:47,030 --> 00:48:49,860 In Pagedraw, you do what we call multistate component. 914 00:48:49,860 --> 00:48:52,650 So again, you can create components in Pagedraw. 915 00:48:52,650 --> 00:48:57,417 And we use them either in Pagedraw or in your outside code. 916 00:48:57,417 --> 00:48:59,250 The way you create a multistate component is 917 00:48:59,250 --> 00:49:01,650 you select the three or four or five or two 918 00:49:01,650 --> 00:49:05,490 or whatever you want states, and click, make multistate 919 00:49:05,490 --> 00:49:11,190 So this created this multistate group up here that has three art boards. 920 00:49:11,190 --> 00:49:19,080 It's a little bit awkward because the background colors are not the same. 921 00:49:19,080 --> 00:49:22,695 Let me copy this background color right here. 922 00:49:22,695 --> 00:49:25,570 Because you can't see the star because the background color is white, 923 00:49:25,570 --> 00:49:27,790 and the stars are also white. 924 00:49:27,790 --> 00:49:30,830 This background color is just being ignored because it's transparent. 925 00:49:30,830 --> 00:49:32,500 So I'm going-- so we can see the star. 926 00:49:32,500 --> 00:49:34,190 There you go. 927 00:49:34,190 --> 00:49:37,370 You can also see the star here. 928 00:49:37,370 --> 00:49:39,260 The other one I can already see. 929 00:49:39,260 --> 00:49:42,620 So now we created these three states for you inside of the multistate group. 930 00:49:42,620 --> 00:49:48,390 And now these three things are all instances of this component. 931 00:49:48,390 --> 00:49:51,410 And if you want to create instances of this component, what you can do 932 00:49:51,410 --> 00:49:53,540 is now you just click, Add, and add here. 933 00:49:53,540 --> 00:49:55,520 You can add all art board stacks, rectangles, 934 00:49:55,520 --> 00:49:57,500 all of these primitives in Pagedraw. 935 00:49:57,500 --> 00:50:01,320 But you can also add your own primitives, which were defined by you. 936 00:50:01,320 --> 00:50:03,940 So desktop HD is, again, one component that you defined. 937 00:50:03,940 --> 00:50:07,240 Because every time you create an art board, you're defining a component. 938 00:50:07,240 --> 00:50:12,210 And multistate group is another such instance that you can create. 939 00:50:12,210 --> 00:50:16,270 So let's actually create desktop HD to see what that looks like. 940 00:50:16,270 --> 00:50:20,010 This one is going to be big, so I'm going to put it here. 941 00:50:20,010 --> 00:50:22,430 This is not going to be useful very much as a component, 942 00:50:22,430 --> 00:50:24,500 because I don't want to reuse this anywhere. 943 00:50:24,500 --> 00:50:26,310 But it can be useful as a preview. 944 00:50:26,310 --> 00:50:28,280 So right now, you see that the props here 945 00:50:28,280 --> 00:50:30,287 are the ones that we defined earlier. 946 00:50:30,287 --> 00:50:32,120 And I can just click, Generate random props, 947 00:50:32,120 --> 00:50:34,070 where it just fills them up for me. 948 00:50:34,070 --> 00:50:37,320 But I can change the movie title to whatever I want-- 949 00:50:37,320 --> 00:50:39,740 Pulp Fiction-- if I want to. 950 00:50:39,740 --> 00:50:41,720 And here, this is another way to have a preview 951 00:50:41,720 --> 00:50:43,050 without having to go back and forth. 952 00:50:43,050 --> 00:50:44,180 If you want, you can just stay in Pagedraw [? and not ?] 953 00:50:44,180 --> 00:50:45,470 have this preview. 954 00:50:45,470 --> 00:50:50,960 More interesting is cases of components that are not previews is actually embed 955 00:50:50,960 --> 00:50:56,260 an instance inside of another component, which we're already doing automatically 956 00:50:56,260 --> 00:50:57,270 for these three guys. 957 00:50:57,270 --> 00:51:00,420 But we didn't do it for the other two guys because we never selected them. 958 00:51:00,420 --> 00:51:01,880 So I'm going to create. 959 00:51:01,880 --> 00:51:05,040 I can do this either by adding or by copy, pasting these guys. 960 00:51:05,040 --> 00:51:12,880 So I'm going to copy, paste this star, and replace the other star with it. 961 00:51:12,880 --> 00:51:18,250 And I'm going to paste another one, and replace this last star also with it. 962 00:51:18,250 --> 00:51:23,020 963 00:51:23,020 --> 00:51:25,930 now notice that all of these guys automatically-- 964 00:51:25,930 --> 00:51:28,600 because we created it as a multistate component-- 965 00:51:28,600 --> 00:51:31,180 already have an input prop-- 966 00:51:31,180 --> 00:51:33,550 prop and input should be the same thing for you-- 967 00:51:33,550 --> 00:51:34,540 called state. 968 00:51:34,540 --> 00:51:37,320 And I can choose to go between default state 1 or state 2. 969 00:51:37,320 --> 00:51:39,270 You can change those names later if you want. 970 00:51:39,270 --> 00:51:42,440 So right now, I'm going to state 1, which is unfilled. 971 00:51:42,440 --> 00:51:44,300 And this one is also going to be state 1. 972 00:51:44,300 --> 00:51:46,900 973 00:51:46,900 --> 00:51:49,880 Now if we go to our React app, you should see that reflected there. 974 00:51:49,880 --> 00:51:51,380 But still there is no functionality. 975 00:51:51,380 --> 00:51:52,255 So I want two things. 976 00:51:52,255 --> 00:51:54,730 I want one, hovering should make it blue. 977 00:51:54,730 --> 00:51:59,730 Two, I need to have a rating that defines which of them are filled 978 00:51:59,730 --> 00:52:00,230 or not. 979 00:52:00,230 --> 00:52:01,900 Hover is very easy with Pagedraw. 980 00:52:01,900 --> 00:52:08,927 You can just call the state that you want hovered its name. 981 00:52:08,927 --> 00:52:10,510 sometimes it's hard to select a block. 982 00:52:10,510 --> 00:52:12,699 It selects a different one when you click here. 983 00:52:12,699 --> 00:52:15,490 You can use the layer list to select the exact block that you want. 984 00:52:15,490 --> 00:52:18,020 In this case, I'm selecting the art board called state 2. 985 00:52:18,020 --> 00:52:23,500 And you can click here to change its name to state 2 colon hover. 986 00:52:23,500 --> 00:52:29,110 This is going to make Pagedraw automatically pick this up and make it 987 00:52:29,110 --> 00:52:33,070 hover state, where now, if we go here-- 988 00:52:33,070 --> 00:52:35,290 bam-- it's ready. 989 00:52:35,290 --> 00:52:38,790 Whenever I hover, I already see the blue star. 990 00:52:38,790 --> 00:52:43,120 The final thing I want to do is have a variable called ratings. 991 00:52:43,120 --> 00:52:46,990 Again, I don't want to have one variable for each of the stars. 992 00:52:46,990 --> 00:52:50,140 I just want to have one rating, which is a number from 0 to 5. 993 00:52:50,140 --> 00:52:53,310 And then, I'll translate that into whatever each of the stars 994 00:52:53,310 --> 00:52:55,090 is filled or not filled. 995 00:52:55,090 --> 00:52:58,330 So first thing, in my constructor, I'm going 996 00:52:58,330 --> 00:53:03,000 to add my final variable here called rating. 997 00:53:03,000 --> 00:53:04,990 And it's going to start as 3. 998 00:53:04,990 --> 00:53:07,189 And I'm going to pass it in. 999 00:53:07,189 --> 00:53:08,980 Everything that I'm passing in here is so I 1000 00:53:08,980 --> 00:53:10,438 can have access inside of Pagedraw. 1001 00:53:10,438 --> 00:53:13,470 Because you have to think of Pagedraw as your render function. 1002 00:53:13,470 --> 00:53:14,875 This dot state dot rating. 1003 00:53:14,875 --> 00:53:18,000 1004 00:53:18,000 --> 00:53:19,860 That's all I need here. 1005 00:53:19,860 --> 00:53:26,080 And in Pagedraw, if I click on each of these guys, 1006 00:53:26,080 --> 00:53:29,699 you see that they have a state. 1007 00:53:29,699 --> 00:53:31,240 And I can trigger between the states. 1008 00:53:31,240 --> 00:53:33,236 But states also can be made dynamic, which 1009 00:53:33,236 --> 00:53:35,860 is what I want to do here, because these states are going to be 1010 00:53:35,860 --> 00:53:37,664 dynamic based on their rating variable. 1011 00:53:37,664 --> 00:53:39,330 So I'll click here, and make it dynamic. 1012 00:53:39,330 --> 00:53:42,290 I'm going to make all of them dynamic. 1013 00:53:42,290 --> 00:53:49,270 2, 3, 4, and 5. 1014 00:53:49,270 --> 00:53:52,000 Now if I go to the code sidebar, you should 1015 00:53:52,000 --> 00:53:56,230 be able to guess now we have five code inputs to fill up, 1016 00:53:56,230 --> 00:53:57,490 one for each of the stars. 1017 00:53:57,490 --> 00:53:59,614 And this is essentially saying, what is the Boolean 1018 00:53:59,614 --> 00:54:01,500 that is going to define the state? 1019 00:54:01,500 --> 00:54:04,162 This has to return some state here. 1020 00:54:04,162 --> 00:54:06,370 And a state is a string that is essentially the name. 1021 00:54:06,370 --> 00:54:07,450 Default versus state 1. 1022 00:54:07,450 --> 00:54:09,010 You could change those names if you wanted to. 1023 00:54:09,010 --> 00:54:10,360 But I'm not going to right now. 1024 00:54:10,360 --> 00:54:12,460 So I'm going to say that this guy-- 1025 00:54:12,460 --> 00:54:15,670 well, the first one. 1026 00:54:15,670 --> 00:54:17,110 The first one is this. 1027 00:54:17,110 --> 00:54:22,450 So this dot props dot rating greater than zero. 1028 00:54:22,450 --> 00:54:23,860 If that's true-- 1029 00:54:23,860 --> 00:54:26,090 I'm using a [? ternary ?] operator here-- 1030 00:54:26,090 --> 00:54:39,350 do state 1, else do default. Now I'll do the same thing for each of these, 1031 00:54:39,350 --> 00:54:40,690 but with different ratings. 1032 00:54:40,690 --> 00:54:44,620 So this guy is 0, 1, 2, 3. 1033 00:54:44,620 --> 00:54:47,280 1034 00:54:47,280 --> 00:54:49,700 This guys is 2. 1035 00:54:49,700 --> 00:54:52,230 This guy is 1. 1036 00:54:52,230 --> 00:54:55,890 And this guy is 4. 1037 00:54:55,890 --> 00:54:58,890 So now this is essentially returning either state 1 or default, 1038 00:54:58,890 --> 00:55:01,350 depending on what my rating is. 1039 00:55:01,350 --> 00:55:05,190 And this is weird. 1040 00:55:05,190 --> 00:55:09,750 I think I did the opposite. 1041 00:55:09,750 --> 00:55:14,010 This dot props dot rating greater than 1. 1042 00:55:14,010 --> 00:55:15,430 I'll do state 1. 1043 00:55:15,430 --> 00:55:16,550 Oh, yeah. 1044 00:55:16,550 --> 00:55:18,350 I actually wanted default as filled. 1045 00:55:18,350 --> 00:55:19,890 So I got this backwards. 1046 00:55:19,890 --> 00:55:21,690 Sorry. 1047 00:55:21,690 --> 00:55:26,550 State 1-- we'll copy, paste again. 1048 00:55:26,550 --> 00:55:36,842 2, 3, 0, and 4. 1049 00:55:36,842 --> 00:55:38,250 Let's see now. 1050 00:55:38,250 --> 00:55:38,850 There you go. 1051 00:55:38,850 --> 00:55:40,470 So 3 is the rating. 1052 00:55:40,470 --> 00:55:44,770 If I change my rating here in the constructor to 1, 1053 00:55:44,770 --> 00:55:48,270 it should hopefully reflect in my app to be 1 star-- perfect. 1054 00:55:48,270 --> 00:55:53,954 Now the final bit is that if I click on a star, I want to change the rating. 1055 00:55:53,954 --> 00:55:55,620 By now, you already know how to do that. 1056 00:55:55,620 --> 00:55:58,480 1057 00:55:58,480 --> 00:56:02,370 The way to do it is to attach an on click handler to each of these stars, 1058 00:56:02,370 --> 00:56:03,600 very simple. 1059 00:56:03,600 --> 00:56:06,990 So my on click handler-- 1060 00:56:06,990 --> 00:56:11,484 again, in the draw sidebar here, I can do event handler on click. 1061 00:56:11,484 --> 00:56:14,400 This one is going to be a little bit more interesting than the others, 1062 00:56:14,400 --> 00:56:19,656 because I can't just say this dot props dot set ratings 1063 00:56:19,656 --> 00:56:22,530 or something like that because I need to know what to set ratings to. 1064 00:56:22,530 --> 00:56:24,167 And it depends on which star it is. 1065 00:56:24,167 --> 00:56:26,250 I could have five functions for each of the stars, 1066 00:56:26,250 --> 00:56:29,520 but that will be kind of not ideal. 1067 00:56:29,520 --> 00:56:36,770 So what I want to do is actually have a function that wraps this thing here. 1068 00:56:36,770 --> 00:56:38,960 That syntax is just wrapping into our function. 1069 00:56:38,960 --> 00:56:42,180 Again, anything here can be arbitrary JavaScript, just like in 1070 00:56:42,180 --> 00:56:45,013 [? the codes. ?] Although you can put arbitrary JavaScript in there, 1071 00:56:45,013 --> 00:56:47,120 and it's going to work. 1072 00:56:47,120 --> 00:56:50,660 we don't advise you to put a lot of JavaScript in there. 1073 00:56:50,660 --> 00:56:51,840 Just keep it simple. 1074 00:56:51,840 --> 00:56:53,715 So this is wrapping into a function, so I can 1075 00:56:53,715 --> 00:56:58,010 do this dot props dot set rating to 1. 1076 00:56:58,010 --> 00:57:03,670 And I'll copy, paste this, add more event handlers, on click. 1077 00:57:03,670 --> 00:57:05,520 These are props I'll set rating 2. 1078 00:57:05,520 --> 00:57:08,120 And I'll just do the same thing for all of them. 1079 00:57:08,120 --> 00:57:13,188 So that's rating 3, on click. 1080 00:57:13,188 --> 00:57:14,100 There you go. 1081 00:57:14,100 --> 00:57:15,270 So set rating 4. 1082 00:57:15,270 --> 00:57:21,325 1083 00:57:21,325 --> 00:57:25,330 Rating 5. 1084 00:57:25,330 --> 00:57:28,120 now I need to implement the separating function. 1085 00:57:28,120 --> 00:57:30,460 Turns out, I already have it implemented here. 1086 00:57:30,460 --> 00:57:33,400 Set rating n this, very simple. 1087 00:57:33,400 --> 00:57:35,560 I'll show you in a second. 1088 00:57:35,560 --> 00:57:42,090 Set rating n just sets the state of rating to be n, very straightforward. 1089 00:57:42,090 --> 00:57:43,621 And now the last bit. 1090 00:57:43,621 --> 00:57:45,370 If you've been following, you know we have 1091 00:57:45,370 --> 00:57:47,470 to pass it into our render function. 1092 00:57:47,470 --> 00:57:55,860 Set rating equals this dot set rating dot find this. 1093 00:57:55,860 --> 00:57:56,730 There you go. 1094 00:57:56,730 --> 00:58:00,750 Now if I click on any star, it changes the rating. 1095 00:58:00,750 --> 00:58:01,950 Awesome. 1096 00:58:01,950 --> 00:58:02,920 So there we go. 1097 00:58:02,920 --> 00:58:07,280 This is our React plus Pagedraw app. 1098 00:58:07,280 --> 00:58:09,230 We can click on stars. 1099 00:58:09,230 --> 00:58:10,810 We can change the movie. 1100 00:58:10,810 --> 00:58:14,420 There's only two movies right now, but you can imagine having a lot more. 1101 00:58:14,420 --> 00:58:17,180 And you can add comments to your movies. 1102 00:58:17,180 --> 00:58:21,340 This movie is awesome. 1103 00:58:21,340 --> 00:58:22,630 And it's working. 1104 00:58:22,630 --> 00:58:26,050 Very cool-- I hope this made sense to all of you. 1105 00:58:26,050 --> 00:58:32,240 So now a few questions, a few follow ups on top of what we just talked about. 1106 00:58:32,240 --> 00:58:36,160 First one is if you're a CS50 student, you're probably thinking about, 1107 00:58:36,160 --> 00:58:39,130 OK, I just learned Python and JavaScript. 1108 00:58:39,130 --> 00:58:43,000 And now there's this React things, and how does this all tie together? 1109 00:58:43,000 --> 00:58:49,990 And it's an interesting idea how to link time together, like the Python stuff 1110 00:58:49,990 --> 00:58:53,900 that you guys did in your problem sets to this context. 1111 00:58:53,900 --> 00:58:56,304 Because in here, we do not have any back hand. 1112 00:58:56,304 --> 00:58:58,720 So we don't have any Python running or anything like that. 1113 00:58:58,720 --> 00:59:01,870 We just have a very simple app that just has frontend. 1114 00:59:01,870 --> 00:59:04,390 And the state is living in the front end here. 1115 00:59:04,390 --> 00:59:06,970 What we probably want is a database that has 1116 00:59:06,970 --> 00:59:09,500 some backend on top of it, which could be in Python, 1117 00:59:09,500 --> 00:59:11,620 could be in Ruby, whatever you want. 1118 00:59:11,620 --> 00:59:13,120 And it is a this dot state. 1119 00:59:13,120 --> 00:59:17,850 Instead of just having these static values, in this JavaScript, 1120 00:59:17,850 --> 00:59:20,330 you'd actually talk to the server. 1121 00:59:20,330 --> 00:59:23,350 So you have a bunch of what we call endpoints, 1122 00:59:23,350 --> 00:59:29,200 or an API, where you talk to the server by querying, what is the current movie 1123 00:59:29,200 --> 00:59:30,250 that the user is seeing? 1124 00:59:30,250 --> 00:59:32,416 And if the user adds a comment, you go into and say, 1125 00:59:32,416 --> 00:59:33,899 hey, database, please update this. 1126 00:59:33,899 --> 00:59:36,440 So there's a little bit of work that you do of the JavaScript 1127 00:59:36,440 --> 00:59:38,710 here using Ajax and technologies like that 1128 00:59:38,710 --> 00:59:45,370 to connect this code to your backed that you probably have. 1129 00:59:45,370 --> 00:59:49,660 The idea here is that Pagedraw does not have anything to do with this, 1130 00:59:49,660 --> 00:59:52,820 neither does React, frankly. 1131 00:59:52,820 --> 00:59:53,950 This is just JavaScript. 1132 00:59:53,950 --> 01:00:00,190 And it's kind of up to you how do that as you see fit. 1133 01:00:00,190 --> 01:00:04,310 Some follow up questions. 1134 01:00:04,310 --> 01:00:06,670 So again, if you've been following, and you 1135 01:00:06,670 --> 01:00:10,000 want to do the exact same this demo that we did today, 1136 01:00:10,000 --> 01:00:12,910 you can go to pagedraw.io, and just click on Login. 1137 01:00:12,910 --> 01:00:15,460 You get redirected to a Google sign in, and you can just 1138 01:00:15,460 --> 01:00:17,780 sign in with any g-mail account. 1139 01:00:17,780 --> 01:00:21,340 But you might find it more helpful to go to documentation.pagedraw.io. 1140 01:00:21,340 --> 01:00:24,400 That's where we explain a lot of the stuff that I've been explaining. 1141 01:00:24,400 --> 01:00:28,750 We have references to the React page as well, Pagedraw CLI, this tutorial, 1142 01:00:28,750 --> 01:00:31,720 which I'm going to update with the Sketch file 1143 01:00:31,720 --> 01:00:34,820 that I just used here as well. 1144 01:00:34,820 --> 01:00:41,080 And again, automating frontend development-- 1145 01:00:41,080 --> 01:00:44,520 a lot of people think it's good for building static landing pages. 1146 01:00:44,520 --> 01:00:46,541 As you guys have hopefully seen, it's actually 1147 01:00:46,541 --> 01:00:49,040 good for building dashboards, and many things as complicated 1148 01:00:49,040 --> 01:00:53,510 as like the Facebook news feed, which we have done in Pagedraw. 1149 01:00:53,510 --> 01:00:56,360 As a matter of fact, Pagedraw itself is done 1150 01:00:56,360 --> 01:00:58,260 in Pagedraw, which is kind of cool. 1151 01:00:58,260 --> 01:01:05,700 So this editor, for example, I can show you guys, we also did in Pagedraw. 1152 01:01:05,700 --> 01:01:08,530 1153 01:01:08,530 --> 01:01:12,600 This part here that you see in the top bar is exactly implemented here. 1154 01:01:12,600 --> 01:01:14,770 You see there's a multistate component. 1155 01:01:14,770 --> 01:01:17,470 And each of these calls a component called 1156 01:01:17,470 --> 01:01:21,760 Topbar button that also has multistates which has three states-- active, hover, 1157 01:01:21,760 --> 01:01:22,870 and so on. 1158 01:01:22,870 --> 01:01:26,550 There's this list to add things right here. 1159 01:01:26,550 --> 01:01:28,040 And you see it right in here. 1160 01:01:28,040 --> 01:01:31,480 So you can, in fact, use Pagedraw to create as complicated [INAUDIBLE] 1161 01:01:31,480 --> 01:01:33,580 as you can imagine. 1162 01:01:33,580 --> 01:01:35,452 And a very good question before is if you 1163 01:01:35,452 --> 01:01:37,910 want to use some functionality from other React components, 1164 01:01:37,910 --> 01:01:42,280 you can always do that override code to add custom components as you see fit. 1165 01:01:42,280 --> 01:01:47,050 1166 01:01:47,050 --> 01:01:48,570 Now some FAQs. 1167 01:01:48,570 --> 01:01:51,070 What if Pagedraw doesn't support something I want to do? 1168 01:01:51,070 --> 01:01:56,985 Well, I just talked about how using custom components. 1169 01:01:56,985 --> 01:01:59,690 The idea is that Pagedraw should support basically 1170 01:01:59,690 --> 01:02:01,940 everything HTML and CSS supports. 1171 01:02:01,940 --> 01:02:04,195 Although, some of it is kind of hidden right now. 1172 01:02:04,195 --> 01:02:06,320 And we're working to make that interface more clear 1173 01:02:06,320 --> 01:02:08,600 and to add more things to the documentation. 1174 01:02:08,600 --> 01:02:10,894 1175 01:02:10,894 --> 01:02:12,810 Probably the most important button in Pagedraw 1176 01:02:12,810 --> 01:02:15,740 today is this little button right here. 1177 01:02:15,740 --> 01:02:19,760 If you click here, and you can type whatever message, 1178 01:02:19,760 --> 01:02:22,550 you can talk to me or to any of us working in Pagedraw right now. 1179 01:02:22,550 --> 01:02:24,714 And we'll help you with whatever problem you have. 1180 01:02:24,714 --> 01:02:26,630 This has been super useful for a lot of people 1181 01:02:26,630 --> 01:02:28,850 building apps with Pagedraw and React. 1182 01:02:28,850 --> 01:02:31,760 1183 01:02:31,760 --> 01:02:34,110 So we have some support for where you want to do. 1184 01:02:34,110 --> 01:02:41,720 But if you really don't, you always have a way 1185 01:02:41,720 --> 01:02:45,260 to do all you want by doing custom components using override code. 1186 01:02:45,260 --> 01:02:46,610 Right 1187 01:02:46,610 --> 01:02:50,630 Second question-- can I manually edit the code that Pagedraw exports? 1188 01:02:50,630 --> 01:02:54,780 Should also be pretty clear by now, but the answer is no. 1189 01:02:54,780 --> 01:02:56,870 As we've seen with Pagedraw Sync, we keep syncing. 1190 01:02:56,870 --> 01:02:59,536 And that code that we exported should be treated as a black box, 1191 01:02:59,536 --> 01:03:03,140 except in some debugging cases, which actually we're 1192 01:03:03,140 --> 01:03:05,570 building some stuff on top of Pagedraw to also help 1193 01:03:05,570 --> 01:03:08,810 you debug these things, which would probably have caught my comments 1194 01:03:08,810 --> 01:03:12,200 with three Ms earlier today. 1195 01:03:12,200 --> 01:03:15,712 But yes, you can not manually edit the code. 1196 01:03:15,712 --> 01:03:17,420 Because if you do manually edit the code, 1197 01:03:17,420 --> 01:03:19,470 we're going to have Pagedraw Sync on top of it. 1198 01:03:19,470 --> 01:03:23,480 And the next time you export, it's going to override all of your changes 1199 01:03:23,480 --> 01:03:24,476 that you manually did. 1200 01:03:24,476 --> 01:03:26,600 Can I collaborate with friends on the same project? 1201 01:03:26,600 --> 01:03:28,730 For sure, especially for CS50 final projects. 1202 01:03:28,730 --> 01:03:29,690 This is a great setup. 1203 01:03:29,690 --> 01:03:32,270 1204 01:03:32,270 --> 01:03:35,930 You can work with your friends, because this is all live collaborated. 1205 01:03:35,930 --> 01:03:43,700 So you can go here to the dashboard, and add collaborators to your project. 1206 01:03:43,700 --> 01:03:47,780 And everyone can go into the same dock and actually edit it live, 1207 01:03:47,780 --> 01:03:51,331 kind of similar to Google Docs style where multiple people are collaborating 1208 01:03:51,331 --> 01:03:51,830 together. 1209 01:03:51,830 --> 01:03:56,120 1210 01:03:56,120 --> 01:03:59,160 If you want support for other frameworks, languages, and some cool 1211 01:03:59,160 --> 01:04:05,610 not so tested features, like Angular, Vue.js, or some backend languages 1212 01:04:05,610 --> 01:04:08,270 as well, like Python Jinja, we do have that. 1213 01:04:08,270 --> 01:04:10,020 Although, it's hidden behind config flags. 1214 01:04:10,020 --> 01:04:12,180 So you can email us at team@pagedraw.io. 1215 01:04:12,180 --> 01:04:15,390 And we can set you up if you want to do that. 1216 01:04:15,390 --> 01:04:17,080 Getting help, this is really useful. 1217 01:04:17,080 --> 01:04:20,160 We can help you on React, Pagedraw, JavaScript, 1218 01:04:20,160 --> 01:04:21,840 whatever you're having trouble with. 1219 01:04:21,840 --> 01:04:23,070 There's a Facebook group. 1220 01:04:23,070 --> 01:04:24,310 You can just follow this. 1221 01:04:24,310 --> 01:04:28,260 We'll hopefully post these slides online afterwards, 1222 01:04:28,260 --> 01:04:29,700 where people help themselves. 1223 01:04:29,700 --> 01:04:33,260 And then there, team@pagedraw.io documentation website 1224 01:04:33,260 --> 01:04:34,230 that I showed you guys. 1225 01:04:34,230 --> 01:04:37,410 And of course, that little message button 1226 01:04:37,410 --> 01:04:39,040 right here, which is really useful. 1227 01:04:39,040 --> 01:04:42,150 1228 01:04:42,150 --> 01:04:44,360 Finally, if you're interested in Pagedraw, 1229 01:04:44,360 --> 01:04:48,580 if you're interested in making web development better 1230 01:04:48,580 --> 01:04:51,550 and you are looking for a job, you can also always email us. 1231 01:04:51,550 --> 01:04:56,150 We're hiring full-time engineers or designers, 1232 01:04:56,150 --> 01:04:59,260 and that's basically it for now. 1233 01:04:59,260 --> 01:05:02,120 If you're a full-time engineer or a designer and you're interested, 1234 01:05:02,120 --> 01:05:03,786 definitely email us at jobs@pagedraw.io. 1235 01:05:03,786 --> 01:05:05,985 Based 1236 01:05:05,985 --> 01:05:07,700 There you go. 1237 01:05:07,700 --> 01:05:09,990 Thank you very much. 1238 01:05:09,990 --> 01:05:12,050 I hope you guys enjoyed this. 1239 01:05:12,050 --> 01:05:15,380 And I hope you guys use Pagedraw and React to build awesome things. 1240 01:05:15,380 --> 01:05:17,530 Thank you very much. 1241 01:05:17,530 --> 01:05:18,737