WEBVTT

00:00.000 --> 00:02.400
Okay, so now it's time to take a look at react components.

00:02.400 --> 00:07.770
Currently what we have is an app component and that's all we really have just a single react component.

00:07.770 --> 00:10.380
And that's not going to cut it for our application.

00:10.380 --> 00:17.790
The way that we typically design a react application is we break our application down into smaller components.

00:17.790 --> 00:24.900
And this situation, what we would typically do is across the top we would have some kind of navbar,

00:24.960 --> 00:31.050
and then we would have a catalog component, for example, that holds a list of our products.

00:31.050 --> 00:37.080
And then for each individual product we would have, let's say a product card that would be its own

00:37.080 --> 00:39.330
react component as well.

00:39.390 --> 00:44.550
And the idea is that initially we're going to start really quite simply, we're going to take a look

00:44.580 --> 00:48.840
at adding a catalog component and then storing our product list inside it.

00:48.840 --> 00:55.800
And the idea is to demonstrate how we can pass down props, things like our product list, for example,

00:55.830 --> 00:59.010
down into another component.

00:59.010 --> 01:04.050
And we'll take a look at that just as a simple example, because at the moment our application, I admit

01:04.050 --> 01:07.020
it looks terrible and we would like to style it a bit better.

01:07.020 --> 01:12.180
But first of all, let's break our component up into smaller components because that makes it easier

01:12.180 --> 01:14.880
to manage our react component as well.

01:14.910 --> 01:16.470
So let's go take a look at this.

01:16.470 --> 01:19.350
And first of all, let's just clean things up at the top.

01:19.350 --> 01:22.050
And inside our features folder.

01:22.050 --> 01:24.330
Let's create a new file.

01:24.630 --> 01:27.420
And it's going to go in a folder called catalog.

01:27.510 --> 01:30.570
So let's first of all specify catalog.

01:30.600 --> 01:37.710
Then we'll say forward slash and use catalog with a capital C because that's the convention for react

01:37.710 --> 01:38.760
components.

01:38.760 --> 01:44.070
And we'll call it catalog dot t s and press return.

01:44.100 --> 01:48.240
So this should be your folder structure at this moment features catalog.

01:48.240 --> 01:50.280
And then our catalog component.

01:50.340 --> 01:57.960
Now one of the extensions we installed earlier on was the Es7 React Redux native React snippets.

01:57.960 --> 02:01.480
There's really just one snippet I really want to use from this.

02:01.630 --> 02:05.920
And to be fair, it doesn't say this a lot of time, but it does save us some time.

02:05.920 --> 02:12.430
And if we type in RFC to make use of this snippet, then this is going to give us a react functional

02:12.430 --> 02:13.180
component.

02:13.180 --> 02:15.910
And what does a react functional component look like?

02:15.910 --> 02:18.910
Well it looks like this export default function catalog.

02:18.910 --> 02:25.240
And we return JSX ex just a div that's populated with the name of the component.

02:25.270 --> 02:31.450
Now what we've got here is an import that's no longer necessary in modern versions of react.

02:31.450 --> 02:38.320
And sure, we can just delete this every time we create a component, but that seems like a repetitive

02:38.320 --> 02:40.510
action that maybe we can avoid.

02:40.510 --> 02:48.700
And if we go to our extensions and we right click the extension and we go to the extension settings,

02:48.700 --> 02:53.740
then this will give us different options for what we can do with this particular extension.

02:53.740 --> 02:56.260
And we've got the setting by default.

02:56.260 --> 02:58.780
This is the import react on top.

02:58.780 --> 03:01.330
We don't need that in modern versions of react.

03:01.330 --> 03:03.240
So we can uncheck that.

03:03.780 --> 03:07.290
And making that small change requires us to restart VSCode.

03:07.290 --> 03:09.720
So we'll click the button to restart VSCode.

03:09.990 --> 03:15.540
And what we should find is if we go back to our component, let's just delete what I currently have

03:15.540 --> 03:16.740
inside there.

03:16.740 --> 03:23.100
And if we type in RFC this time, then it creates the component just how we need it.

03:23.130 --> 03:25.320
We don't have that import at the top.

03:25.680 --> 03:26.280
So great.

03:26.310 --> 03:27.810
Now we've got our catalog component.

03:27.840 --> 03:28.680
How do we use it?

03:28.710 --> 03:32.460
How do we tell our app root component about this component?

03:32.460 --> 03:42.270
If we go back to our app dot TSX, then what we're going to have inside our JSX is instead of returning

03:42.480 --> 03:48.630
an H1 here, for example, and our list of products, our goal is to return the catalog, the list of

03:48.630 --> 03:54.750
products from the catalog component, and for the time being, to demonstrate how we pass things down

03:54.750 --> 03:55.710
to components.

03:55.740 --> 04:01.800
We'll keep the logic inside our root component, but this is not our ideal desired state to have all

04:01.800 --> 04:07.510
of this functionality and logic inside this component, but it will suffice for the short term.

04:07.840 --> 04:13.990
And in order to use our catalog component inside the app component, then just underneath the H1, for

04:13.990 --> 04:20.050
the time being, we make a left angle brackets, and then we type in the name of our component.

04:20.050 --> 04:26.950
And VSCode should bring up the automatic import of where this component is coming from, which in this

04:26.950 --> 04:31.870
case is the features catalog, and then the catalog component.

04:31.870 --> 04:34.090
So we can accept that automatic import.

04:34.090 --> 04:39.670
And then we close off this component with the forward slash and right angle brackets.

04:39.670 --> 04:44.710
And we should have in our imports the catalog import there as well.

04:44.740 --> 04:50.500
If we go and take a look at our browser, what we can see is we are displaying that component inside

04:50.500 --> 04:51.190
our browser.

04:51.220 --> 04:55.480
Now not doing anything just now of course, but it will do soon.

04:55.480 --> 04:58.060
So let's take our list of products.

04:58.060 --> 05:03.440
Let's take the unordered list and for the short term we'll take the button as well.

05:03.470 --> 05:07.130
This is not some functionality that we're going to leave as.

05:07.160 --> 05:11.840
We're going to focus on the user interface for displaying products, filtering products, sorting products

05:11.840 --> 05:12.800
initially.

05:12.800 --> 05:17.510
And we're not going to deal with any Crud operations, such as adding a product until much later on

05:17.510 --> 05:18.440
in the course.

05:18.500 --> 05:24.320
But just as a demonstration of how we can do certain things, I'll keep it in place at the moment.

05:24.320 --> 05:30.140
So I'm going to cut this functionality, the unordered list and the button, and I'm going to go to

05:30.170 --> 05:33.260
the catalog and I'm going to put it inside here.

05:33.770 --> 05:37.100
Now what we've got here is the same problem that we faced earlier.

05:37.100 --> 05:42.410
When we're returning something from a function, we can only return one element.

05:42.410 --> 05:45.980
We can't return two elements, but we can create a wrapper element.

05:45.980 --> 05:49.940
And we can return as many children of that wrapper element as we need.

05:49.940 --> 05:52.760
So earlier on I used a div for example.

05:52.850 --> 05:58.850
And I'll cut the unordered list in the button and I'll put it inside here and just reformat.

05:59.000 --> 06:04.560
But this div we don't need this div unless we're going to use it for some styling purposes, and we

06:04.560 --> 06:07.440
want to apply some CSS at this level.

06:07.470 --> 06:11.250
If we don't need to apply styling, then we don't need the div.

06:11.250 --> 06:18.720
And this div outputs into the rendered HTML and it's visible inside our domain object model.

06:18.720 --> 06:21.150
And we simply don't need that at this stage.

06:21.150 --> 06:25.470
So what we can do instead is effectively use a react fragment.

06:25.500 --> 06:29.250
Now we can use a fragment component from react.

06:29.250 --> 06:32.280
And we could technically import this into here.

06:32.280 --> 06:34.140
And that didn't import.

06:34.140 --> 06:41.010
So if I just used a quick fix and add the import then this imports the fragment from react JS.

06:41.790 --> 06:43.590
And that solves the problem.

06:43.680 --> 06:48.450
And the fragment will not be output into our HTML.

06:48.930 --> 06:51.180
But again we don't need to do that either.

06:51.180 --> 06:53.070
And we can shortcut this.

06:53.070 --> 06:57.450
Or the shorthand way of doing this is just to have empty angle brackets.

06:57.450 --> 07:00.540
And that is the equivalent of a react fragment.

07:00.570 --> 07:09.650
This is not output into our rendered HTML, but it does give us the wrapper component or wrapper element

07:09.650 --> 07:11.510
to contain these two different elements.

07:11.510 --> 07:15.380
And then we don't need to import the fragment from react either.

07:15.470 --> 07:20.270
Now we do have an issue of course, because we need our products inside this catalog.

07:20.300 --> 07:26.270
Now we could of course cut the code from the App.tsx and use it directly in the catalog.

07:26.270 --> 07:31.340
But I want to demonstrate the concept of props inside a react component.

07:31.370 --> 07:35.540
Every react component can receive props from its parent component.

07:35.540 --> 07:43.790
The App.tsx is a parent of the catalog, and we can pass down to the catalog a list of our products.

07:43.790 --> 07:45.710
And I could say products equals.

07:45.710 --> 07:47.660
And then in curly brackets.

07:47.660 --> 07:53.840
This is the property in the catalog that we're receiving, the products into which we haven't created

07:53.840 --> 07:54.440
yet.

07:54.440 --> 07:58.790
And then we can pass down our list of products to the catalog component.

07:59.300 --> 08:01.760
So how do we use that inside our catalog.

08:01.760 --> 08:09.120
Well inside the parameters for this component, we can specify that we're going to receive props from

08:09.120 --> 08:10.080
the parent component.

08:10.110 --> 08:12.480
Now for the short term I'm just going to use.

08:12.510 --> 08:15.660
And that should be props not props for the short term.

08:15.660 --> 08:17.490
I'm just going to use the any type.

08:17.490 --> 08:18.390
I know it's not allowed.

08:18.390 --> 08:20.430
We'll come back and deal with that very soon.

08:20.430 --> 08:32.010
But just as a short demonstration, if I specify props dot products inside here, then the props is

08:32.010 --> 08:32.760
coming.

08:33.420 --> 08:39.480
Then the props is an object and it contains the products that we're passing down from the App.tsx.

08:39.720 --> 08:41.970
We've also got something else that's a problem inside here.

08:41.970 --> 08:43.020
This function.

08:43.050 --> 08:46.680
We can also pass functions down to lists as well.

08:46.680 --> 08:53.070
And if we go ahead and do that we've got our add product function.

08:53.280 --> 08:59.880
And we could also pass down the add product and set this equal to add product and make this available

08:59.880 --> 09:01.980
inside our catalog component.

09:01.980 --> 09:03.730
If I go back to the Catalog.

09:03.790 --> 09:08.590
Then we could specify props dot add product inside here.

09:08.590 --> 09:14.230
And what we should have, even though we've got some warnings, is the functionality will be retained.

09:14.230 --> 09:20.440
So if I go back I can see that I've got my list of products and I should still be able to add products.

09:20.770 --> 09:26.980
And the code for this is no longer in our app dot TSX, as in the JSX itself.

09:26.980 --> 09:31.000
We're passing that down as props to the catalog component.

09:31.180 --> 09:34.300
So that's how we pass these properties down.

09:34.300 --> 09:37.690
But obviously we've got some warnings to deal with inside here.

09:37.690 --> 09:40.210
We know the functionality is working, but this isn't good.

09:40.240 --> 09:47.770
The item implicitly has an any type, because TypeScript is not able to infer what this item is because

09:47.770 --> 09:49.600
I've used the any type here.

09:49.600 --> 09:52.210
So we don't have any type safety inside here.

09:52.210 --> 09:53.650
And I can make a mistake.

09:53.650 --> 09:59.380
And I'm not going to be informed about it because we're not using TypeScript as intended.

09:59.380 --> 10:01.840
And if I go back and check, then I've lost the product names.

10:01.840 --> 10:03.550
But I'm not seeing the warning here.

10:03.560 --> 10:07.460
but I do get good warnings up here to tell me that something is not quite.

10:07.490 --> 10:08.150
Right.

10:08.150 --> 10:09.680
So how do we deal with this then?

10:09.710 --> 10:13.130
Well, typically what we do is above the component.

10:13.130 --> 10:14.750
We'd specify a type.

10:14.750 --> 10:16.580
And I'm going to call the type props.

10:16.580 --> 10:21.170
And I'll pretty much consistently always call the type props that we're going to be using here.

10:21.170 --> 10:26.660
And then we let our component know what type of things it's going to be receiving from its parent component.

10:26.660 --> 10:29.750
So in this case we're going to get a list of products.

10:29.750 --> 10:32.540
And this is a type of product array.

10:32.960 --> 10:37.550
And also we're going to get an add product function passed down here.

10:37.550 --> 10:43.940
And we need to specify the signature of this function as its type.

10:43.940 --> 10:46.220
Now the signature of the add product function.

10:46.220 --> 10:52.760
If we go and take a look at this well it's just an add product that doesn't take any parameters nor

10:52.760 --> 10:54.020
does it return anything.

10:54.020 --> 10:58.160
All it's doing is setting the products inside the Usestate hook.

10:58.250 --> 11:02.990
So the signature for this method is.

11:03.020 --> 11:07.120
And if we hover over the ad product, it tells us exactly what the signature is.

11:07.150 --> 11:09.010
Empty parentheses.

11:09.010 --> 11:12.670
The arrow returning void as in it's not returning anything.

11:12.670 --> 11:15.490
So that's the type that we use inside here.

11:15.490 --> 11:20.470
For the ad product, we'll just specify empty parentheses that returns void.

11:20.830 --> 11:23.920
And then we can give our props its type.

11:23.920 --> 11:26.890
And I can specify props inside here.

11:26.890 --> 11:28.330
And then everything's happy.

11:28.330 --> 11:29.620
We've got rid of the warnings.

11:29.620 --> 11:31.930
The item is no longer any type.

11:31.930 --> 11:33.880
Now it's a type of product.

11:34.480 --> 11:37.630
And what we can also do now is because we've got a product type.

11:37.630 --> 11:39.460
We don't need the index here anymore.

11:39.460 --> 11:40.930
So we can remove that.

11:40.930 --> 11:49.450
And instead of the index here, we can use the item.id as the unique key for each of these list items.

11:49.480 --> 11:56.380
Now this is not typically how we'd use the props either, because there is the concept of destructuring

11:56.380 --> 11:59.410
inside JavaScript and TypeScript.

11:59.620 --> 12:01.750
Destructuring means that I can.

12:01.780 --> 12:08.690
Instead of specifying props here, I can specify curly brackets and for each of the properties inside

12:08.690 --> 12:10.970
the object, the props object.

12:11.000 --> 12:18.410
I can name them inside here and use them directly instead of using props, dot products, dot map or

12:18.410 --> 12:20.090
props dot add products.

12:20.090 --> 12:26.720
I can simply use products and add product without the use of the word props in front of them, and it

12:26.720 --> 12:34.070
makes our code a bit cleaner, more understandable, more clear about what's happening inside this component.

12:34.070 --> 12:39.440
And we should have all of our original functionality working just as it did before.

12:39.590 --> 12:40.400
Marvelous.

12:40.400 --> 12:44.900
But the problem is, our application looks awful and we need to address that.

12:44.900 --> 12:50.030
And to help us out with that, we're going to use a react component library, a very popular one called

12:50.030 --> 12:55.940
material UI, which gives us some react components to help us with things like buttons and our lists.

12:55.940 --> 13:02.210
And it's also going to give us some styling utility classes that will help us make our application look

13:02.210 --> 13:03.140
more presentable.

13:03.140 --> 13:05.570
And we'll take a look at adding that next.
