Okay, so now it's time to take a look at react components.
Currently what we have is an app component and that's all we really have just a single react component.
And that's not going to cut it for our application.
The way that we typically design a react application is we break our application down into smaller components.
And this situation, what we would typically do is across the top we would have some kind of navbar,
and then we would have a catalog component, for example, that holds a list of our products.
And then for each individual product we would have, let's say a product card that would be its own
react component as well.
And the idea is that initially we're going to start really quite simply, we're going to take a look
at adding a catalog component and then storing our product list inside it.
And the idea is to demonstrate how we can pass down props, things like our product list, for example,
down into another component.
And we'll take a look at that just as a simple example, because at the moment our application, I admit
it looks terrible and we would like to style it a bit better.
But first of all, let's break our component up into smaller components because that makes it easier
to manage our react component as well.
So let's go take a look at this.
And first of all, let's just clean things up at the top.
And inside our features folder.
Let's create a new file.
And it's going to go in a folder called catalog.
So let's first of all specify catalog.
Then we'll say forward slash and use catalog with a capital C because that's the convention for react
components.
And we'll call it catalog dot t s and press return.
So this should be your folder structure at this moment features catalog.
And then our catalog component.
Now one of the extensions we installed earlier on was the Es7 React Redux native React snippets.
There's really just one snippet I really want to use from this.
And to be fair, it doesn't say this a lot of time, but it does save us some time.
And if we type in RFC to make use of this snippet, then this is going to give us a react functional
component.
And what does a react functional component look like?
Well it looks like this export default function catalog.
And we return JSX ex just a div that's populated with the name of the component.
Now what we've got here is an import that's no longer necessary in modern versions of react.
And sure, we can just delete this every time we create a component, but that seems like a repetitive
action that maybe we can avoid.
And if we go to our extensions and we right click the extension and we go to the extension settings,
then this will give us different options for what we can do with this particular extension.
And we've got the setting by default.
This is the import react on top.
We don't need that in modern versions of react.
So we can uncheck that.
And making that small change requires us to restart VSCode.
So we'll click the button to restart VSCode.
And what we should find is if we go back to our component, let's just delete what I currently have
inside there.
And if we type in RFC this time, then it creates the component just how we need it.
We don't have that import at the top.
So great.
Now we've got our catalog component.
How do we use it?
How do we tell our app root component about this component?
If we go back to our app dot TSX, then what we're going to have inside our JSX is instead of returning
an H1 here, for example, and our list of products, our goal is to return the catalog, the list of
products from the catalog component, and for the time being, to demonstrate how we pass things down
to components.
We'll keep the logic inside our root component, but this is not our ideal desired state to have all
of this functionality and logic inside this component, but it will suffice for the short term.
And in order to use our catalog component inside the app component, then just underneath the H1, for
the time being, we make a left angle brackets, and then we type in the name of our component.
And VSCode should bring up the automatic import of where this component is coming from, which in this
case is the features catalog, and then the catalog component.
So we can accept that automatic import.
And then we close off this component with the forward slash and right angle brackets.
And we should have in our imports the catalog import there as well.
If we go and take a look at our browser, what we can see is we are displaying that component inside
our browser.
Now not doing anything just now of course, but it will do soon.
So let's take our list of products.
Let's take the unordered list and for the short term we'll take the button as well.
This is not some functionality that we're going to leave as.
We're going to focus on the user interface for displaying products, filtering products, sorting products
initially.
And we're not going to deal with any Crud operations, such as adding a product until much later on
in the course.
But just as a demonstration of how we can do certain things, I'll keep it in place at the moment.
So I'm going to cut this functionality, the unordered list and the button, and I'm going to go to
the catalog and I'm going to put it inside here.
Now what we've got here is the same problem that we faced earlier.
When we're returning something from a function, we can only return one element.
We can't return two elements, but we can create a wrapper element.
And we can return as many children of that wrapper element as we need.
So earlier on I used a div for example.
And I'll cut the unordered list in the button and I'll put it inside here and just reformat.
But this div we don't need this div unless we're going to use it for some styling purposes, and we
want to apply some CSS at this level.
If we don't need to apply styling, then we don't need the div.
And this div outputs into the rendered HTML and it's visible inside our domain object model.
And we simply don't need that at this stage.
So what we can do instead is effectively use a react fragment.
Now we can use a fragment component from react.
And we could technically import this into here.
And that didn't import.
So if I just used a quick fix and add the import then this imports the fragment from react JS.
And that solves the problem.
And the fragment will not be output into our HTML.
But again we don't need to do that either.
And we can shortcut this.
Or the shorthand way of doing this is just to have empty angle brackets.
And that is the equivalent of a react fragment.
This is not output into our rendered HTML, but it does give us the wrapper component or wrapper element
to contain these two different elements.
And then we don't need to import the fragment from react either.
Now we do have an issue of course, because we need our products inside this catalog.
Now we could of course cut the code from the App.tsx and use it directly in the catalog.
But I want to demonstrate the concept of props inside a react component.
Every react component can receive props from its parent component.
The App.tsx is a parent of the catalog, and we can pass down to the catalog a list of our products.
And I could say products equals.
And then in curly brackets.
This is the property in the catalog that we're receiving, the products into which we haven't created
yet.
And then we can pass down our list of products to the catalog component.
So how do we use that inside our catalog.
Well inside the parameters for this component, we can specify that we're going to receive props from
the parent component.
Now for the short term I'm just going to use.
And that should be props not props for the short term.
I'm just going to use the any type.
I know it's not allowed.
We'll come back and deal with that very soon.
But just as a short demonstration, if I specify props dot products inside here, then the props is
coming.
Then the props is an object and it contains the products that we're passing down from the App.tsx.
We've also got something else that's a problem inside here.
This function.
We can also pass functions down to lists as well.
And if we go ahead and do that we've got our add product function.
And we could also pass down the add product and set this equal to add product and make this available
inside our catalog component.
If I go back to the Catalog.
Then we could specify props dot add product inside here.
And what we should have, even though we've got some warnings, is the functionality will be retained.
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.
And the code for this is no longer in our app dot TSX, as in the JSX itself.
We're passing that down as props to the catalog component.
So that's how we pass these properties down.
But obviously we've got some warnings to deal with inside here.
We know the functionality is working, but this isn't good.
The item implicitly has an any type, because TypeScript is not able to infer what this item is because
I've used the any type here.
So we don't have any type safety inside here.
And I can make a mistake.
And I'm not going to be informed about it because we're not using TypeScript as intended.
And if I go back and check, then I've lost the product names.
But I'm not seeing the warning here.
but I do get good warnings up here to tell me that something is not quite.
Right.
So how do we deal with this then?
Well, typically what we do is above the component.
We'd specify a type.
And I'm going to call the type props.
And I'll pretty much consistently always call the type props that we're going to be using here.
And then we let our component know what type of things it's going to be receiving from its parent component.
So in this case we're going to get a list of products.
And this is a type of product array.
And also we're going to get an add product function passed down here.
And we need to specify the signature of this function as its type.
Now the signature of the add product function.
If we go and take a look at this well it's just an add product that doesn't take any parameters nor
does it return anything.
All it's doing is setting the products inside the Usestate hook.
So the signature for this method is.
And if we hover over the ad product, it tells us exactly what the signature is.
Empty parentheses.
The arrow returning void as in it's not returning anything.
So that's the type that we use inside here.
For the ad product, we'll just specify empty parentheses that returns void.
And then we can give our props its type.
And I can specify props inside here.
And then everything's happy.
We've got rid of the warnings.
The item is no longer any type.
Now it's a type of product.
And what we can also do now is because we've got a product type.
We don't need the index here anymore.
So we can remove that.
And instead of the index here, we can use the item.id as the unique key for each of these list items.
Now this is not typically how we'd use the props either, because there is the concept of destructuring
inside JavaScript and TypeScript.
Destructuring means that I can.
Instead of specifying props here, I can specify curly brackets and for each of the properties inside
the object, the props object.
I can name them inside here and use them directly instead of using props, dot products, dot map or
props dot add products.
I can simply use products and add product without the use of the word props in front of them, and it
makes our code a bit cleaner, more understandable, more clear about what's happening inside this component.
And we should have all of our original functionality working just as it did before.
Marvelous.
But the problem is, our application looks awful and we need to address that.
And to help us out with that, we're going to use a react component library, a very popular one called
material UI, which gives us some react components to help us with things like buttons and our lists.
And it's also going to give us some styling utility classes that will help us make our application look
more presentable.
And we'll take a look at adding that next.