WEBVTT 0 00:00.120 --> 00:06.690 Hey guys in this lesson we're going to level up our knowledge around React components and to do that 1 00:06.690 --> 00:12.630 we're going to learn about something called props. So head over to the starting code sandbox and go ahead 2 00:12.720 --> 00:16.650 and fork it. And once you have it 3 00:16.650 --> 00:23.140 feel free to download it to use in your local environment or follow along with me in code sandbox. 4 00:23.160 --> 00:32.040 So here I've got a really simple contacts app. So I've got three people that I supposedly know their names, 5 00:32.040 --> 00:38.820 a picture of them that I found on the Internet, some fake phone numbers and fake emails. As you can see 6 00:38.910 --> 00:47.850 if we look inside our inde.js, this is pretty repetitive and it's also very long. And this is 7 00:48.000 --> 00:55.080 one of the perfect use cases for React components because we have these repetitive elements that is 8 00:55.170 --> 01:00.530 cluttering up our code making it very long and very complex unnecessarily. 9 01:01.560 --> 01:07.350 So let's go ahead and extract each of these contacts as a brand new component. 10 01:07.470 --> 01:12.100 I'm going to create it just inside my index.js so you can see quite easily 11 01:12.570 --> 01:15.870 both the component and the rendering side by side. 12 01:16.020 --> 01:22.590 And I'm going to call this component a new card like a contact card, and it's going to return 13 01:22.590 --> 01:24.630 each of these contact items. 14 01:24.630 --> 01:30.030 So I'm just going to cut Beyonce out of there and I'm going to insert her into a div. 15 01:30.030 --> 01:38.480 So now this h2 image and two paragraph elements are now being returned from my card function. 16 01:38.520 --> 01:45.340 Now I'm actually just gonna go ahead and take out these other guys from my render function and I'm gonna 17 01:45.360 --> 01:47.950 keep my website as simple as I can 18 01:48.030 --> 01:50.490 so you can see easily what's happening. 19 01:50.640 --> 01:57.750 So instead of having all of those divs, I can now create maybe three cards instead 20 01:57.750 --> 01:58.050 right? 21 01:58.230 --> 02:07.530 So I've got three cards like so, and once it reloads you can see that yes I do have three cards which 22 02:07.860 --> 02:12.790 all have an h2 image and two paragraphs but they're all of Beyonce. 23 02:12.900 --> 02:14.660 So that's not what I want. 24 02:14.700 --> 02:21.750 Instead I want to have different pieces of information in each of these reusable card components. With 25 02:21.750 --> 02:23.550 the knowledge that we've gotten so far, 26 02:23.850 --> 02:31.770 it's actually very difficult to make these components reusable. And it's because we haven't got any ability 27 02:32.130 --> 02:40.840 to send these card components some custom data so that each of the cards gets rendered differently. 28 02:41.030 --> 02:45.930 Now let's think about how this problem is solved in plain old HTML. 29 02:46.340 --> 02:52.640 So if we had over to the index.html and let's just go ahead and delete all of our cards from here so 30 02:52.640 --> 03:00.130 that we clear up our screen. And right below my root div where we know our React components are going 31 03:00.130 --> 03:01.240 to be rendered, 32 03:01.340 --> 03:07.040 I'm gonna go ahead and create just a plain HTML element. And remember that when you're creating a React 33 03:07.040 --> 03:09.990 app you're not limited to just using React. 34 03:10.130 --> 03:16.910 You can just insert it any way you like using a div with a particular id. And the rest of the file 35 03:16.940 --> 03:21.430 can still be worked like a regular JavaScript or HTML file. 36 03:21.500 --> 03:28.370 So that means if you have an existing website, it's really easy to just insert a root div and then start 37 03:28.490 --> 03:32.390 adding React code into that particular position. 38 03:32.390 --> 03:38.720 So I'm going to create a plain HTML element which is going to be an input element and I'm going to 39 03:38.720 --> 03:40.820 make itself closing as well. 40 03:40.820 --> 03:48.970 And you can see that it shows up in here as a little text box. Now this input element has attributes 41 03:49.030 --> 03:52.950 right? Attributes which I can set with custom values. 42 03:53.050 --> 03:57.580 For example, I could change the id of this input. 43 03:57.580 --> 03:59.820 Let's call it fName 44 03:59.890 --> 04:05.860 so like a field to input your first name, and then I can also give it a placeholder. 45 04:05.950 --> 04:11.020 So I could say that enter your first name. 46 04:11.020 --> 04:16.010 And once we refresh you can see the place holder goes up in gray. 47 04:16.300 --> 04:21.290 And I can even set the value even before the users had a chance to interact with it. 48 04:21.310 --> 04:28.230 So let's just say I'm going to put my own name in there and you can see that I've now got an input field 49 04:28.620 --> 04:33.030 with a value that's already pre-existing inside. 50 04:33.060 --> 04:37.460 And if I delete it and make it empty, then you'll get to see my placeholder text. 51 04:38.280 --> 04:47.040 So this is kind of a way for us to pass custom pieces information via these attributes to a particular 52 04:47.210 --> 04:48.360 HTML element 53 04:48.390 --> 04:49.360 right? 54 04:49.410 --> 04:57.060 And if we go ahead and take a look at this app in a separate tab and I open up my Chrome developer tools 55 04:57.540 --> 05:04.530 then I can actually access this element by just grabbing hold of document.getElementById and we 56 05:04.530 --> 05:06.680 call it fName. 57 05:06.690 --> 05:11.010 So this should actually get hold of this particular input element. 58 05:11.010 --> 05:16.380 And I'm going to save it into a variable. I'll just call it input and then hit enter. 59 05:16.380 --> 05:22.960 So now I've got this input value stored then I can actually access all of its values. 60 05:22.980 --> 05:29.950 I can say input.placeholder to print out the value of the placeholder attribute. 61 05:30.000 --> 05:38.160 I can also say something like input.value to print out the current value of the inputs and I can even 62 05:38.160 --> 05:39.270 change this right? 63 05:40.560 --> 05:50.010 So effectively we're using these attributes from our HTML elements to use and custom pieces of data to 64 05:50.010 --> 05:51.750 that particular element. 65 05:51.750 --> 05:58.950 And over here when we tap into that element using get element by id and we have a reference to it, then 66 05:58.950 --> 06:05.790 you can see it's almost like as if we have the input as an object and we're accessing each of its properties 67 06:05.820 --> 06:10.190 like .placeholder or .value. 68 06:10.200 --> 06:18.330 Now these attributes are predetermined and there are lists of them in the MDN docs but we can't 69 06:18.330 --> 06:21.140 go beyond what is actually here. 70 06:21.300 --> 06:24.320 We can't define our own custom attribute 71 06:24.330 --> 06:25.160 right? 72 06:25.170 --> 06:32.720 If I created something called, I don't know, just angela and I tried to give it a value. 73 06:33.390 --> 06:42.360 And I go into my React app and I try to tap into input.angela, that doesn't actually work. But if 74 06:42.360 --> 06:51.840 you think about your React components almost as a custom HTML element then we can define these attributes. 75 06:52.470 --> 06:59.460 And in the React component world, those attributes are called properties and you'll usually hear them 76 06:59.460 --> 07:09.670 referred to as props. Let's say that I decided to create a new card component from my card function. And 77 07:09.670 --> 07:17.980 what happens behind the scenes is it's almost like I'm calling this function card and it returns a custom 78 07:18.100 --> 07:27.270 HTML element based on my instructions. But when we take a look at these custom React components, we can 79 07:27.270 --> 07:33.390 pass properties using very similar syntax to what you saw over here. 80 07:33.810 --> 07:41.520 So if I go ahead and cut this input out of my index.html and I paste it down here just below my 81 07:41.520 --> 07:48.640 card, you can see that with our card component we can do exactly the same thing. 82 07:48.660 --> 07:58.440 So I can pass my card a value, for example name, and I can set that equal to Beyonce for example. And 83 07:58.500 --> 08:07.110 when this card component gets created, it will have a property called name that's set to equal to Beyonce 84 08:07.110 --> 08:14.910 And we can get hold of it by adding a name to the inputs to access those things that are sent over. 85 08:15.480 --> 08:23.250 And it's customary to call this props. For example inside this function I can console log the value of 86 08:23.250 --> 08:30.270 props and if I hit save and we take a look in our console, you can see that it receives an object. 87 08:30.270 --> 08:36.430 And currently the object just has one property with a value set to Beyonce. 88 08:37.020 --> 08:45.540 So what this means is that in fact, we can actually completely remove all of these hard coded parts of 89 08:45.600 --> 08:52.700 our React Components and instead rely on inserting the values of these props. 90 08:52.740 --> 09:00.770 So I could say props.name which I know to be the property that I sent over and it's equal to 91 09:00.770 --> 09:01.650 Beyonce. 92 09:02.100 --> 09:10.320 And now what I can do is I can for example copy the source and add that as a property. So I'll create 93 09:10.320 --> 09:19.210 a new property called image and set it to equal the URL of that image. I will create a property called 94 09:19.360 --> 09:28.920 tel for telephone and I'll set it equal to that number. And I'll also create a property called 95 09:28.930 --> 09:33.990 email which I'll set equal to that made up email. 96 09:33.990 --> 09:42.300 So now inside our card component I can access that object called props which has all of these properties 97 09:42.300 --> 09:49.900 passed in as an object and I can tap into each of these properties as long as I know what they are called. 98 09:49.950 --> 09:56.940 So the source was stored inside a property called img, so I can write props.img. 99 09:57.600 --> 10:04.800 But remember that this is Javascript and we're inside an beyondelement inside our JSX file. 100 10:04.890 --> 10:13.050 So be sure to enclose it in a set of curly braces if you want it to be interpreted as Javascript. 101 10:13.050 --> 10:16.670 Next I've got my props. 102 10:16.710 --> 10:23.260 tel and my props.email. 103 10:23.470 --> 10:27.700 So I've ended up with exactly the same card as before 104 10:27.700 --> 10:34.840 but the crucial difference is that this card no longer contains any Beyonce specific information. 105 10:34.840 --> 10:43.440 And what I can do now is I can create as many of these cards as I need with different pieces of information. 106 10:43.720 --> 10:51.850 And I want to pose this as a challenge to you. Go ahead and try to create another card with an imaginary 107 10:51.850 --> 10:58.180 contact if you wish or a real contact even, and see if you can add a second card to our website. 108 10:58.180 --> 11:03.640 That second card should appear just below Beyonce but it should have a different name, a different 109 11:03.700 --> 11:10.210 image, email and phone number. Pause the video now and see if you can successfully reuse our custom card 110 11:10.210 --> 11:14.410 component. 111 11:14.660 --> 11:14.960 All right. 112 11:14.990 --> 11:20.170 So I'm going to create another card and this is a self closing tag with no children. 113 11:20.390 --> 11:23.540 And I'm going to add some properties. 114 11:23.630 --> 11:31.300 And remember that because inside our card function it's looking for these properties name, image, 115 11:31.310 --> 11:35.540 tel, email. We have to keep it consistent in between the cards. 116 11:35.630 --> 11:39.580 So let's say that name is Jack Bauer. 117 11:39.620 --> 11:45.460 Img is equal to some sort of image that I find online. 118 11:45.680 --> 11:54.500 And then we've got tel which will set equal to some random numbers and email we'll set equal to 119 11:58.360 --> 11:59.130 so perfect. 120 11:59.140 --> 12:07.750 We've now got two cards with completely different information and we're able to reuse this card component 121 12:08.110 --> 12:11.550 with all of its structure as well as styling if you wish. 122 12:11.560 --> 12:18.330 So these could actually have class names associated with them or inline styling if you wish 123 12:18.430 --> 12:26.890 but all we need to do here in our render function is to provide the customized pieces of data and everything 124 12:26.890 --> 12:31.900 that stays the same lives inside this card component. 125 12:31.990 --> 12:39.070 So now as you can imagine, if you wanted a contact list with many many people, you can simply just reuse 126 12:39.130 --> 12:41.780 your card component. 127 12:42.140 --> 12:44.090 And this brings us to a good point. 128 12:44.150 --> 12:51.170 If you remember previously, I said that if you had a style let's say let's just give it a class name 129 12:51.630 --> 13:00.860 let's just call it my style, and all it does is changes the text color to red and we save that CSS file 130 13:01.160 --> 13:04.610 and we go back into our React code, 131 13:04.610 --> 13:10.460 you can see that if I was to add that class to my div for example. 132 13:10.550 --> 13:19.070 So I'll say className = "my-style" and I hit save and refresh my websites, 133 13:19.130 --> 13:28.100 all the text inside that div has been changed to red right? But I can't do the same thing inside my custom 134 13:28.160 --> 13:29.620 card component. 135 13:29.690 --> 13:36.920 I can't for example add the class name attribute and then apply my-style. Even if I refresh a million 136 13:36.920 --> 13:37.370 times 137 13:37.370 --> 13:38.510 it's still not going to work. 138 13:39.080 --> 13:46.730 And this is because inside our custom components, it sees each of these as a custom property. 139 13:46.730 --> 13:52.280 So it thinks that you're making up a name called className and you would like to access it inside this 140 13:52.370 --> 13:59.990 card component under the props object instead of seeing it as an HTML attribute. 141 13:59.990 --> 14:08.210 So whenever you're using HTML predetermined attributes, they always have to go into the HTML elements which 142 14:08.270 --> 14:12.450 are highlighted in different color and also they're in lower case. 143 14:12.470 --> 14:19.730 So this is the reason why we can't do that. But inside our custom components, we can create any name we 144 14:19.730 --> 14:24.050 want and associate it with any value we need. 145 14:24.050 --> 14:32.750 So it's almost like we're calling this card function and passing over an object through the input called 146 14:32.750 --> 14:33.500 props. 147 14:33.680 --> 14:42.500 And then inside the function we, use those inputs to customize this HTML element and then we return 148 14:42.500 --> 14:50.980 it and output it into our DOM to be seen on the website. In summary with HTML attributes, 149 14:51.040 --> 14:58.870 we have the HTML tag and then we have a space and we get to use these predetermined fixed name attributes 150 14:58.870 --> 15:01.390 such as id or place holder or value. 151 15:01.480 --> 15:05.810 And these of course depend on the actual element that we're using. 152 15:06.160 --> 15:12.160 And when we use these attributes, we can pass in some custom data. And that data can then be accessed 153 15:12.250 --> 15:20.650 on the element by tapping into say the .id or .placeholder or .value properties. 154 15:20.650 --> 15:25.390 Now when it comes to React, what we have is a very similar structure. 155 15:25.450 --> 15:33.850 So we have our custom components and we can create as many of these properties or props as we wish, we 156 15:33.850 --> 15:35.950 can name them anything we like. 157 15:35.950 --> 15:36.970 They're not fixed. 158 15:37.000 --> 15:39.370 Nobody has defined them ahead of time. 159 15:39.400 --> 15:47.110 In fact you are the one that's creating this custom card element and you get to specify which attributes 160 15:47.140 --> 15:48.570 or properties they should have. 161 15:49.060 --> 15:55.810 But these values for each of these properties then gets passed along when this card component is created. 162 15:55.870 --> 16:04.780 And when we output this HTML element we can incorporate those properties into the creation of that element. 163 16:04.780 --> 16:08.780 And it's usually via an input called props. 164 16:09.070 --> 16:15.190 So the easiest way to imagine it is just simply that you're creating a new Javascript object with these 165 16:15.250 --> 16:22.960 key and value pairs and then that whole object gets sent over as the props object and then you can tap 166 16:22.960 --> 16:25.270 into it using .name, .telephone, 167 16:25.270 --> 16:31.300 as long as they match up with the names in your component element. In the next lesson, we're going to 168 16:31.300 --> 16:37.480 test out your understanding of props and you're going to be using everything you learn here to complete 169 16:37.570 --> 16:43.950 a challenge and build out a fully fledged contacts app. So for all of that and more, I'll see you there.