Introduction to Components
Okay then, so in this lesson we're going to talk about components. And just like with a lot of other front-end frameworks, we build applications in Solid using components. For those unfamiliar with components, they're just a way to break different parts of our applications up into their own standalone sections that kind of come together to make the website. And pretty much everything that you're going to see in your website is going to be a component or part of a component.
For example, the navbar of your site could be a component. If you've got a footer, that could be its own components. The page itself, the page content in between the header and the footer, could be a component. And you might also have reusable UI components that can appear in multiple times in your website, like a card component. And you can also nest components within each other. For example, these card components are nested within the main page component. So generally speaking, your entire application is made from this combination of different components that can be nested within other components.
And all together they make what's known as a component tree. And this idea of a component tree is nothing new. It's used in loads of other front-end frameworks like React, Vue, Svelte, etc. And breaking an application down this way into components just makes it easier to manage different sections of the website and make these sections more reusable as well.
SolidJS Components and JSX
So let's take a quick look at how to make some components in Solid JS. So in its simplest form, a component in Solid is just a function that returns a JSX template like this one here. The App component is just a function called App that returns a JSX template, and we export this function. And by the way, JSX stands for JavaScript XML, and it just allows us to write this HTML-like code within these JavaScript functions, which can then be compiled and inserted into the DOM as HTML elements so that we can see it in a browser. And you can see over in the file name that it actually has a .jsx extension too. Now this is all very similar to how React looks so far as well, where components are just functions that return a JSX template. And also if you wanted to use TypeScript instead of JavaScript in Solid, you can do. But in that case, these files would have a .tsx extension instead of .jsx. We're going to use JavaScript because I want to keep the barrier for learning Solid quite low, but feel free to use TypeScript if you prefer.
The Root Component
So this App component that was already made for us when we started this project is the root component. And that means it sits at the very top of the component tree, and all other components will ultimately be nested inside this one or further down the tree nested inside child components. Now, the reason it's the root component is because this is the component that's rendered in the index.jsx file over here. So this file that basically kickstarts the application renders the App component right here. And whatever component is rendered here is going to be the root component. It's the one that ultimately gets injected into the DOM at this location in the HTML page. And remember that HTML page is down here outside of the source folder.
Component Naming and Structure
So anyway, let's go back to the App component and take a look at what else is inside it. So first of all, the name of the function, App, it starts with a capital, and this is a naming convention Solid wants you to stick to. So when you make new components, always use PascalCase when you name the component function. And PascalCase just means start every word with a capital letter like this.
So then we have the JSX template right here which gets returned, and that represents the contents that we see in the browser when we preview this. But also inside this function, we can write other JavaScript like functions or store variables, etc.
Now we're going to look into all of that a little bit more as we go along, but for now I want to flesh out this template a little bit more and also maybe make another component too, which we can then nest inside this component as well.
Building the App Component Layout
Okay, so to begin with, I'm going to get rid of this import up here, we don't need that anymore. And in fact, we can just delete the app.module.css file as well. Now I'm going to delete all of this template as well inside here. And now we're down to basics, right? We have the function that's returning nothing at the minute, so we need to return a JSX template.
Now, the first thing I want to note is that when we're returning a template, we have to return only one root element. So that means for example, we can have a div right here and other stuff inside that, but on the same level as this div, we can't have another element, for example another div and return two root elements inside this template. We can't do that. We have to have a single root element. So in our case, that's going to be a div. But what if you didn't want a div or any other kind of tag? Well, you can use a fragment instead if you want, which is just basically an empty tag. And then you could have multiple different elements inside here, and it doesn't matter now that these are all siblings on the same level because we have the one single fragment surrounding all of them. All right?
So that's important. We just need one root element inside this return template. Okay, so we've got a div. And then the first thing I'll do is a header. And inside that header, we'll just do an H1 for now, which is Ninja Merch. And then after the header, we'll maybe do an image which is a banner or something. Now, what I'm going to do is actually bring in an image into the assets folder, banner.png. Now this is up on the GitHub repo if you want to grab this as well. But now we can import that image up here in a file. So I'm going to say import and we're going to import the banner and it's going to come from ./assets/banner.png.
So now we can use this banner as the source over here. Now we're outputting something dynamic so we use curly braces. And inside here we can just say banner which is this thing right here. So now the source is going to be resolved to this thing right here. And for the alt, we'll just say site banner. All right, so let's save this now and preview in the browser. Okay, and in the browser, we can see now we have the title over here and the banner here as well. Awesome.
Creating and Nesting a Reusable Component
Now the next thing I want to do is to create another component and nest that component inside this App one right here. So what I'm going to do is create a new folder over here called components. And typically what I do is any UI components or reusable components that I make, I put them inside a components folder. You don't have to do that, that's just what I do. And then inside here, we're going to make a new component called Card.jsx. So this is going to be a UI component eventually where the style of it is going to look very much like a little card, and we can put different content in it depending on where we want to use it.
So for now, let's keep this really simple. I'm going to export something, so export default function Card. And the reason we're exporting this is just so we can import it in other files. And then we're going to return a template inside here. So return parentheses, and then it's going to be a div that surrounds some content. So an H2 for example, this is just going to say Card Component. And then beneath that, we'll do a paragraph tag, and this paragraph is going to have some lorem ipsum. So we'll say lorem 15, and that's just 15 words, essentially. Save that.
And now we can use this Card component inside our App component. So what I'm going to do is come down here and output Card. I'm going to click on this, and it imports it up here at the top for us. So this is self-closing at the minute because we don't need an opening and closing tag for the card because nothing at the minute is going in between it. Later on, we'll look at that, but for now we don't need to. So this is going to be self-closing to begin with. And in fact, we'll output it three times. And we can do that. We can reuse these different UI components as many times as we want, wherever we want. So let's save that and preview again in the browser.
All right, cool. So now we can see these three card components, the title and the paragraph in each one. Now everything looks crap at the minute, and that's because we've not styled it. We're going to look at that later on, but at least we know how to get these different components now onto the page.
How SolidJS Components Render
Now there's one more thing I want to mention about these component functions in Solid JS. They only ever run once in the browser and then they're pretty much destroyed. So when they first run, solid.js compiles the template inside the component and it also tells Solid's reactive system about everything in the component that needs to be tracked. Then, it gets rid of the component completely.
So if I were to use some reactive values in this component and maybe use those values in the template as well, the component would essentially tell Solid's reactive system to track those values when the function first runs. And then after that, the component never needs to run again because the reactivity is handled outside of the component by Solid's reactive system, which now knows about those tracked values, and it can surgically update the DOM whenever those tracked values change. So you can kind of think of the component function in Solid as just a setup function that sets things up for Solid, and it only ever runs once.
Now, that's in contrast to React, where if you use state or reactive values inside a React component, the whole component and any child components rerun when those values change, which could be considered one of the drawbacks of React. So again, in Solid JS, the component functions only ever run once. And that does have implications because if I was to run some kind of console log in this component up here to log, I don't know, some kind of state that I might have later on, or even some other code entirely, then that code would only run once as well when the component function first runs, because after that the component function is essentially destroyed.
Now you can get around this by using an effect, which we will look at later on, but on its own, it would only run once. So that's something to be aware of if you are coming from a React background because it's a bit different. And also we will talk a little bit more about this kind of behavior and Solid's reactive system using signals later on in the course. So don't worry if this doesn't make too much sense right now.
All right, cool. So now we've seen how to make and also nest components. Next up, let's look at how we can add some CSS to these templates to make them look a little bit nicer.