In the beginning of this module, I was extolling the virtues of React component and how wonderful it
is to be able to break down a large website into individual compact and reusable components,
but up until now we've actually not used any components.
So in this lesson, that's what we're going to tackle.
We're going to learn all about React components.
So go ahead and get the starting version of the sandbox from the Course Resources and then fork it
to have your own copy.
So if you remember previously when we had our code for the styling practice, you saw that it's kind of
getting out of hand, right?
We actually have to scroll to be up to see the entire page. And a lot of research has actually found
that the more that you have to scroll and the longer a single file is, the harder it is to understand
the code that's in it.
So components really allow us to split up a large file or a complex web structure into smaller components.
And we also get the added benefit of reusing each of these components when we need the same functionality,
which happens a lot on web.
So in the starting file, I've got this h1 and an unordered list,
so this is a bit of code that I've gotten from one of the previous lessons. And I want to show you how
we can actually split up this entire website into smaller components.
So the first thing I'm going to do is I'm going to create a heading component.
Now while at the moment it's just a simple h1 element and you would question yourself like, 'Do I really
need to split this into a separate component?'
But in reality as you can imagine once you've added all the styles and you'd probably have a div around
the heading, you might have some sort of navigation bar,
I've kept the code intentionally simple just so we can easily see at a glance what's happening, but know
that in reality, your heading component is probably a lot longer and a lot more complex and definitely
worth splitting into a separate component.
So if I want to create a component that just has this h1, I would start by creating a function.
So I would give my function a name and notice how in this case, it's React convention to give your components
a name that is in PascalCase, which means that every single word has the first letter capitalized.
And so in my case let me call this component Heading and let's open up a set of parentheses and open
up a set of curly braces.
Now in this heading function, all that it's going to do is to return a HTML element that is created using
JavaScript.
So I'm going to cut this h1 and I'm going to make it the output of my Heading function.
So it's just going to return this h1.
Now I can use this custom Heading component inside my React code as if it was an HTML element.
So I'm going to insert it back where I had it before, right here, and I'm going to create it just as I
would for any other HTML tag, like so.
But notice where this React convention comes in handy. All of our components have names which start with
a capital letter using PascalCase,
and this allows React to differentiate between the custom components that we're building, versus the
HTML elements that we're trying to get hold of, that exists in the DOM. Now that we've created our Heading
component, and we've inserted it in here as if it was an HTML element,
you can see it shows up in our website in exactly the same position.
And what's happening behind the scenes is once it gets to this line, it looks for this custom component
called Heading, which it finds right here, and then it triggers this function and outputs the h1 to replace
it in the location of this component.
Now remember that by convention again, if we have an HTML element that has no children,
so nothing in between the opening and closing tags, then the best practice is to actually have a self-closing
tag.
So the name of the component, a space, a forward slash and the closing angle bracket. And in fact even
if you didn't do this and if you're in CodeSandbox and you've got the linter in place, if you hit Save
it'll actually just replace it for you.
Now, if you're wondering where I'm getting hold of all of these supposed best practices, this is the Airbnb
React JSX style guide, and it's generally accepted to be a good reference as to how to for example,
name things in your code, or what to do with spacing,
for example, having a single space after the component and then the closing tags. So be sure to bookmark
this and refer to it whenever you are in doubt as to how you should be writing or structuring your code.
Now at the end of the day of course the compiler in the browser doesn't actually care, but it's a case
of having your code being easily readable by other programmers, as well as to make it easy to understand
what's going on when you come back to it later on.
So in this case I've split off the heading into a separate component called, Heading, but it's still living
inside my index.js right?
And you can imagine that if I had a very large website and I had all of my components cluttering index.js,
that would be terrible.
So we're going to use an ES6 feature where we import our Heading component from a separate file, and it's
going to be very similar to what we're doing with React and ReactDOM.
But in this case we're going to be doing all of the importing and exporting ourselves.
So inside our src folder, I'm going to click on this icon to create a new file as it suggests, and
that file is going to be called, Heading, which is the name of my component, '.jsx'.
So I'm going to start using this JSX file name to denote all of my components which are going to
be written in JSX.
Again, if you take a look at the convention, we will usually leave index.js as a plain JavaScript
file even if we're using some React and some JSX in it,
and then we would have all of our components separated into individual files with the jsx extension.
Let's go ahead and move our Heading component, and cut it out of index.js and paste it into our
Heading.jsx.
Now, if you remember from previous lessons, I mentioned that in order to actually write this code
which is not actually JavaScript, it's in fact JSX, because we have these HTML elements which are
intermingling with actual JavaScript code, and we're only able to do this because the React module actually
converts this into real JavaScript using real JavaScript functions such as document.createElement
et cetera.
So in order to use this code, we of course have to import React from the "react" module.
So I'm going to copy that line and paste it at the top here and you're going to be doing this every
time you create a new React component. Now that we've imported React, so we're able to write JSX code
and we've got this Heading function which is a component that we want to use inside our index.js
right here,
how do we actually get this file, to know about this file?
Well, we have to use the ES6 import export functionality. In the file where we've got our component,
we're going to export this Heading function as the default export.
So I'm going to write 'export default Heading' and notice how I'm not going to add the parentheses because
this is going to make it return immediately,
instead I actually want to use it as a component
so inside an HTML tag like so. I've got my export default Heading, and now I can cap it off with a semicolon.
Now this file is creating a Heading function and exporting it to whichever file needs it.
This is the file that needs it and in order to use it I'm going to import it.
So I'm going to import Heading from that "Heading.jsx" file.
So I'm going to use the relative path
so ./, and then Heading.jsx
,
but of course, in ES6, the extension of the file is actually optional.
So if you had a file called Heading.js or Heading.jsx, you can actually remove the entire
extension and just have the name of the file.
It'll be able to figure out and find this file just with this amount of information.
Now all of our errors are gone and I've now got my Heading being rendered in my website using ReactDOM,
and I'm using my custom Heading component which came from the heading file which is the Heading.jsx
file that I've got right here, and it's being created as a function that has an output.
Here's your turn to try it out.
I want you to create a custom component called List which will comprise of this unordered list and all
of the three items in it.
Try and see if you can remember how we imported Heading, from the Heading file, how we created our custom
component,
and if you're successful you should you have to delete all of this and simply just have a List component
here, and our website should work just as it did before.
Pause the video now and try to give this a go.
All right.
So here's our unordered list which we want to split off into a separate file.
So I'm going to go ahead and create a new file inside my src folder.
Make sure that you don't press on this button because that's just going to create a new folder and you
won't get to do anything with it.
So click on this button and let's create our new component,
and we said we'd call it List.jsx is going to be the extension and then hit Enter to create it.
Now, inside all of our React components, we mentioned that we need to import the react module in order
to actually be able to write JSX.
So we've got that import Heading in there, and then we're going to create a function that's going to
return this unordered list item.
So let's copy that and over here I'm going ti create my function called List.
And then inside this function I'm going to return everything that used to be in my index.js, which
is my unordered list and the three list items.
So now all I have to do to ship this function over to here or any other file that needs it, is to export
it as the default.
And the thing that I want to export is of course this function called List, without the parentheses.
So now that I've created my custom component over here, I can now replace all of this with my custom
List component which is again, going to be a self-closing tag because it has no children, so nothing in
between the open and closing tags.
Now I'm getting an error here because it says List is not defined and that is because we need to import
this List from that file "./List".
And that way it'll actually know about that function called List and be able to use it in here and
render it as the custom component.
Now, normally what you'll see in the index.js of a lot of React apps is they don't actually have any
HTML elements like a div or an h1 or anything like that,
instead, what you'll see is it just has a custom component called App. And instead of all of these things,
we would have a custom file called App.jsx and inside here we would have all import statements,
our import React as well, and we would render our component as a function called App() which returns a div
which contains that Heading custom component, as well as, the List custom component,
and then it will export this as the default export, and be able to use it inside here by importing App
from "./App".
So this is the most common structure that you'll see.
So index.js has pretty much no custom code
other than rendering the React App, and then in our App.js we've got the start of our component
tree and then we start seeing these HTML elements as well as custom components.
So in this lesson, we've seen how we can split up a very simple structure which we've got here into custom
components,
and this way our code is now a lot more modular.
Each of these files are a lot shorter and a lot more manageable.
And remember that each of these components can now be reused as and when we want to.
So if I wanted another list down here for some reason, then I can just create another List component
without having to write out or the ul's or li's etc..
And as we learn more about these components and how to use things such as props, we'll be able to customize
these components to an even higher degree. The last thing I want to mention in this lesson is that, usually
in React apps you will have a lot of component files, and as you can imagine if you have 20 or 30 of
these then this whole list is going to start needing some structure.
So the very basic thing we should do is to at least create a new directory called components and inside
this directory we'll drag in all of our React components.
Now of course as your app gets more complex then you would probably start splitting off this component
folder into even subfolders like a login screen component, or a register screen component, or subdivisions
just to make your files more easily manageable.
But now that we've moved all our components into a separate folder, our index.js is going to break
because our App.jsx is no longer at the same level,
so we now have to change this relative path to "./components/App", and now everything starts
working again. In the next lesson, we're going to get some more practice with React components and you're
going to be separating out some components from an index.js file that is clearly on its way to turning
into spaghetti code.
So for all of that and more, I'll see there.