Part 2: Use and Style React Components
Introduction
In the previous part of the Tutorial, you started your first Gatsby site and used Gatsby Cloud to deploy it to the internet. Now that you have everything all set up, it’s time to make this site your own!
To build out the basic page structure for your blog site, you’ll need to know about React components and how Gatsby uses them.
By the end of this part of the Tutorial, you will be able to:
- Create page components to add new pages to your site.
- Import and use a pre-built component from another package.
- Create your own reusable “building block” component.
- Use component props to change the way a component renders.
- Use the
children
prop to create a wrapper component.
Prefer a video?
If you’d rather follow along with a video, here’s a recording of a livestream that covers all the material for Part 2.
You can catch the stream live on Wednesdays at 10AM Pacific Time / 5PM UTC on the Gatsby Twitch channel.
A quick intro to React
What is React?
React is the JavaScript library that Gatsby uses under the hood to create user interfaces (UIs). With React, you can break down your UI into smaller, reusable pieces called components.
For example, imagine the UI for an online store’s Products page:
To build this page in React, you might have a <Navbar>
component for the navigation menu, a <Sidebar>
component for extra information displayed to the side of the main content, and a <ProductGrid>
component to display all of the products for sale.
You can also create components from other components. For example, you might decide to break down the <ProductGrid>
component into a list of multiple <ProductCard>
components, which each display the details about a single product. This pattern is called composition, since your larger <ProductGrid>
component is composed of smaller <ProductCard>
components.
Try it!
Look back at the finished example blog site. How might you break down the pages into components?
Not sure where to start? Look for parts of the UI that repeat within a page or across multiple pages.
What is a React component?
Under the hood, a React component is a function that returns a React element. A React element is an object that React uses to render DOM elements.
The simplest way to write React elements is with JSX. JSX is a JavaScript syntax extension that describes the DOM structure for your component. It looks a bit like having HTML in your JavaScript files:
So a simple React component might look something like this:
You’ll learn more about how to create React components in the next section.
Create a page component
There are two main types of components in a Gatsby site. The first type you’ll create are page components. A page component contains all the UI elements for a specific page of your site.
In this section, you’ll create two new page components: one for the Home page and one for an About page.
(If you’re new to writing React components, expand the content below for a quick overview.)
Key React Concept: Writing a React component
There are three main steps to writing a React component:
- Import React from the
'react'
package, so that you can use JSX inside your.js
file. - Define your component. It should be a function that returns a JSX element.
- Export your component, so that it can be used by other parts of your site.
Here’s an example of what that basic structure looks like in code:
Your component must return a single React element, but you can put as many elements inside that top-level element as you want. The code snippet below shows an example of a valid component and an invalid component:
If you try to build your site with the code above, you’ll get an error for <InvalidComponent>
like this:
Task: Update the home page content
Now that you’ve gotten a high-level introduction to React, it’s time to try your hands at writing some React components. To start, you’ll update the content for the home page.
If you haven’t already, open your Gatsby site in Visual Studio Code, and start up your local development server in the command line:
- Open your command line application.
- Change directories into the folder for your Gatsby site.
- Run
gatsby develop
. - Open
localhost:8000
in your web browser.
- Open your
src/pages/index.js
file. Replace its contents with the following. (Notice how the component’s structure matches the three steps for writing React components?)
- Go to
localhost:8000
in a web browser. (You might need to wait a moment while your development server rebuilds.) Once your page updates, it should look something like this:
Key Gatsby Concept 💡
Gatsby automatically creates pages for React components that are the default export of files in the src/pages
directory.
If a user tries to visit the URL for a page that doesn’t actually exist, Gatsby will use the src/pages/404.js
page component to display an error instead. Go ahead and give it a try! (If you’re trying it on localhost:8000
you’ll need to click the “Preview custom 404 page” button on the development 404 page.)
Task: Create a new page component for an About page
Now that you’ve updated the existing Home page, try creating a new page from scratch. Make an About page, so that you can tell people a little about yourself.
- Create a new file:
src/pages/about.js
. Use the code below as a starting point for your About page. (Feel free to switch up the content to make it more specific to you. Maybe share your favorite food or go-to vacation spot!)
- In a web browser, visit
localhost:8000/about
. When your development server finishes rebuilding your site, the About page should look something like this:
Key Gatsby Concept 💡
Pages created in the src/pages
directory use the name of the file as the route for the page.
For example, if you had a file called src/pages/garden-gnomes.js
, you could access that page at localhost:8000/garden-gnomes
.
Use the <Link>
component
Now that you’ve built a few page components, it’s time to look at the other type of React components in a Gatsby site: “building-block” components.
Note: The term building-block component isn’t an official technical term. It’s just the best name we could come up with to describe this kind of component.
Building-block components are smaller components that represent just a part of a page’s user interface (instead of an entire page). Think back to the store website example from the “What is React?” section. The Navbar
, Sidebar
, ProductGrid
, and ProductCard
components are examples of building-block components. You can combine several smaller building-block components into a larger page component.
One of the powerful things about building-block components is that you can reuse the same component in multiple places across your site. This is especially useful for pieces of your UI that share a similar structure but render different values.
For example, each of the ProductCard
components in the product grid above shows a photo of the product, the product name, a short description, the price, and a link to the product page. The exact values change for each product, but the general structure stays the same. By making the ProductCard
component dynamic, you can reuse the same code for all the products in the grid!
React has a built-in feature to help you make your components dynamic: properties (or props, for short).
Key React Concept: Components with props
You can use component props to change the way a component renders. Props are essentially arguments that you pass into your component function.
The code snippets below show an example of how to pass a prop into a component when it’s rendered and how to use the value of that prop within the component definition:
When you define your component, it should take in a single argument: an object called
props
. Theprops
object will have whatever properties you passed into your component when you rendered it.
Syntax Hint: In JSX, you can embed any JavaScript expression by wrapping it with {}
. That’s how you can access the value of the name
prop from the props
object.
When rendering the
Greeting
component, you pass in thename
prop with a specific value, like"Megan"
. You could swap in a different value string each time you render theGreeting
component.
You can name your props whatever you want. For example, if you passed in iceCreamFlavor="mint chip"
when you rendered a component, that prop would be available to use inside your component at props.iceCreamFlavor
.
So far, your blog site has two separate pages (Home and About), but the only way to get from one page to the other is to update the URL manually. It would be nice to add links to make it easier to switch between pages on your site.
The Link
component is an example of a pre-built component that you can use in your site. In other words, the Link
component is defined and maintained by another package (in this case, the Gatsby package). That means you can import it and use it in your own components without knowing too much about how it works under the hood.
The Link
component lets you add a link to another page in your Gatsby site. It’s similar to an HTML <a>
tag, but with some extra performance benefits. The Link
component takes a prop called to
, which is similar to the <a>
tag’s href
attribute. The value should be the URL path to the page on your site you want to link to.
Key Gatsby Concept 💡
The Gatsby Link
component provides a performance feature called preloading. This means that the resources for the linked page are requested when the link scrolls into view or when the mouse hovers on it. That way, when the user actually clicks on the link, the new page can load super quickly.
Use the Link
component for linking between pages within your site. For external links to pages not created by your Gatsby site, use the regular HTML <a>
tag.
Follow the steps below to add Link
components to your Home and About pages.
- On the Home page, import the
Link
component from the Gatsby package and add a link to your About page.
- On the About page, import the
Link
component from the Gatsby package and add a link to your Home page.
- In your web browser, click on each of the links to make sure they’re working correctly.
Create a reusable layout component
If you take another look at the finished example blog, you might notice that there are some repeated parts of the UI across each page, like the site title and the navigation menu.
You could copy those elements into each page of your site separately. But imagine your site had dozens (or even thousands) of pages. If you wanted to make a change to the structure of your navigation menu, you’d have to go and update every one of those files separately. Yuck.
Instead, it would be better to create one common Layout
component that groups all the shared elements to reuse across multiple pages. That way, when you need to make updates to the layout, you can make the change in one place and it will automatically be applied to all the pages using that component.
In this section, you’ll create your first custom building-block component: Layout
. To do that, you’ll need to use a special React prop called children
.
Key React Concept: Components with children
In addition to the props that you can add to your components, React also creates certain props for your components automatically.
One such prop is called children
. When you render a component, the children
prop will automatically be passed whatever content comes between the opening and closing tags for that component. This is helpful when you want to create a component that wraps some generic content.
The Link
component you used in the last section also used the children
prop. You used it to pass in the text to be hyperlinked.
Think of your wrapper component as a picture frame. A frame has its own shape and style, but you can swap out its contents with whatever you want. You could use the same picture frame around a photo of a house or a statue. You could even put in something besides a picture, like a painting or a piece of embroidery.
Here’s an example of what the code for this scenario might look like. First, when the <Frame>
component is rendered, it has contents passed in between the opening and closing tag:
Then in the component definition, the children
prop will get passed whatever elements came between the opening and closing tag. You can render the children
prop in your JSX to insert the contents.
In the browser, the actual DOM elements will look something like this:
Follow the steps below to create a Layout
component and add it to your Home and About pages.
- Create a new file called
src/components/layout.js
. Insert the following code to define yourLayout
component. This component will render a dynamic page title and heading (from thepageTitle
prop), a list of navigation links, and the contents passed in with thechildren
prop. To improve accessibility, there’s also a<main>
element wrapping the page-specific elements (the<h1>
heading and the contents fromchildren
).
Syntax Hint: You might have noticed that the Layout
component uses a slightly different syntax for its props.
Now instead of looking like this:
…it looks like this:
This is a JavaScript technique called destructuring. It’s basically a shortcut for defining variables based on an object’s properties. It’s like saying, “Take the object that gets passed into this function, and unpack its pageTitle
and children
properties into their own variables.”
In other words, it’s a shorter way to do the following:
- Update your Home page component to use the Layout component instead of the hard-coded
Link
component you added in the previous section.
- Update your About page component to use the Layout component as well.
- Check your Home and About pages in a web browser to make sure your new
Layout
component is working:
Style components with CSS Modules
Now that you’ve got your page structure set up, it’s time to add some style and make it cute!
Gatsby isn’t strict about what styling approach you use. You can pick whatever system you’re most comfortable with.
In this Tutorial, you’ll use CSS Modules to style your components. This means that styles will be scoped to components, which helps avoid class naming collisions between components. Gatsby is automatically configured to handle CSS Modules - no extra setup necessary!
Key Styling Concept: CSS Modules
To define styles using CSS Modules, put your CSS in a file that ends with the file extension .module.css
. This tells Gatsby that this CSS file should be processed as a CSS Module rather than plain CSS.
Within your CSS file, create separate CSS classes for each element you want to style. For example:
Then, in your component .js
file, import each class separately and apply it to the corresponding React element:
If you open the developer console in your web browser and inspect the <h1>
element, you’ll see that it has a long classname like my-component-module---title---2lRF7
. That’s the class name generated by CSS Modules. It’s guaranteed to be unique across your site, even if you have another component that also has a .title
class in its .module.css
file. That’s one of the reasons CSS Modules are a popular styling approach: they let you write CSS that’s scoped to your components, so you don’t have to worry about selector name collisions between components.
Follow the steps below to style your Layout
component using CSS Modules.
Create a new file:
src/components/layout.module.css
. (The.module.css
part at the end is important! That’s what tells Gatsby that these styles are using CSS Modules.)Start by adding a single
.container
class:
- Then import that class into your
Layout
component.js
file, and use theclassName
prop to assign it to the top-level<div>
element:
Syntax Hint: To apply classes to React components, use the className
prop. (This is another example of a built-in prop that React automatically knows how to handle.)
This might be confusing if you’re used to using the class
attribute on HTML elements. Do your best to not mix them up!
- When you open your local site in a web browser, you should now see the font has changed and the content is more centered on the page.
- Now that you’ve seen how to style a single element for your component, add some more styles to apply to the other elements in your
Layout
component.
- Import the new classes into your
Layout
component, and apply each class to the corresponding element.
Syntax Hint: In CSS, the convention is to name classes using kebab case (like .nav-links
). But in JavaScript, the convention is to name variables using camel case (like navLinks
).
Luckily, when you use CSS Modules with Gatsby, you can have both! Your kebab-case class names in your .module.css
files will automatically be converted to camel-case variables that you can import in your .js
files.
- Once your development server finishes rebuilding your site, you should see your new styles applied in your web browser:
Want to see how it all fits together? Check out the commit history in the GitHub repo for the finished example site.
Summary
Congratulations, you’ve made it to the end of Part 2! 🥳 (That was a long one!)
Take a moment to think back on what you’ve learned so far. Challenge yourself to answer the following questions from memory:
- What’s the difference between a page component and a building-block component?
- How do you add a new page to your Gatsby site?
- What are the three steps for writing a new React component?
- What are props and when might you use them?
- What is the
children
prop and why is it useful?
Ship It! 🚀
Before you move on, deploy your changes to your live site on Gatsby Cloud so that you can share your progress!
First, run the following commands in a terminal to push your changes to your GitHub repository. (Make sure you’re in the top-level directory for your Gatsby site!)
Once your changes have been pushed to GitHub, Gatsby Cloud should notice the update and rebuild and deploy the latest version of your site. (It may take a few minutes for your changes to be reflected on the live site. Watch your build’s progress from your Gatsby Cloud dashboard.)
Key takeaways
- React is a library that helps you break down your UI into smaller pieces called components. A component is a function that returns a React element. React elements can be written in JSX.
- Page components contain all the UI elements for a specific page of your site. Gatsby automatically creates pages for components that are the default exports of files in the
src/pages
directory. The name of the file will be used as the route for the page. - Building-block components are smaller reusable parts of your UI. They can be imported into page components or other building block components.
- You can import pre-built components (like
Link
) from other packages, or you can write your own custom components from scratch (likeLayout
). - You can use props to change how a component renders. You can define your own props when you build a component. React also has some built-in props, like
children
andclassName
. - Gatsby isn’t opinionated about what styling approach you want to use, but it works with CSS Modules by default.
Share Your Feedback!
Our goal is for this Tutorial to be helpful and easy to follow. We’d love to hear your feedback about what you liked or didn’t like about this part of the Tutorial.
Use the “Was this doc helpful to you?” form at the bottom of this page to let us know what worked well and what we can improve.
What’s coming next?
In Part 3 of the Tutorial, you’ll learn about how to use Gatsby plugins to add more pre-built functionality to your site.
Continue to Part 3