Skip to main content

4.2 - React Components

Learning Goals:

  • Understand components and component-based architecture
  • Learn how to create, import, and export components
  • Organizing components to build a UI

Components: UI Building Blocks

react component diagram

Components are the reusable pieces of UI (user interface) of a React application, defined as functions or classes. A component can be as small as a button, or as large as an entire page.

React components are JavaScript functions that return HTML-like code called JSX:

JSX : Connecting React to HTML

What is JSX?

JSX (JavaScript XML) is a syntax extension that allows you to write HTML-like code within JavaScript.

JSX is stricter than HTML. You have to close tags like <br />. Your component also can’t return multiple JSX tags. You have to wrap them into a shared parent, like a <div>...</div> or an empty <>...</> wrapper:

    function AboutPage() {
return (
<>
<h1>About</h1>
<p>Hello there.<br />How do you do?</p>
</>
);
}

Build a component

There are two different types of components: functional and class-based. In this course we will focus on functional components.

Here's an example:

export default function Profile() {
return (
<img
src="https://elaineimagelink.jpg"
alt="Elaine"
/>
)
}

Step 1: Export the component

  • The export default prefix is standard JavaScript syntax that tags the main function in a file so you can later import it from other files.

Step 2: Define the function

  • With function Profile() { } you define a JavaScript function with the name Profile.
warning

Capitalize the names of your components or else they won't work!

This is because React needs to distinguish components from (lowercase) HTML tags, like <br>.

Step 3: Add JSX

  • The component below returns an <img /> tag with src and alt attributes.
return <img src="https://elaineimagelink.jpg" alt="Elaine" />;

If your markup isn’t all on the same line as the return keyword, you must wrap it in a pair of parentheses:

return (
<div>
<img src="https://elaineimagelink.jpg" alt="Elaine" />
</div>
);
// Without parentheses, any code on the lines after return will be ignored!

Now you have successfully built a component!


Use a component

Now that you’ve defined your Profile component, you can nest it inside other components. For example, you can export a Gallery component that uses multiple Profile components:

function Profile() {
return (
<img
src="https://elaineimagelink.jpg"
alt="Elaine"
/>
);
}

export default function Gallery() {
return (
<section>
<h1>Amazing scientists</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}

Nest and Organize Components

Components are regular JavaScript functions, so you can keep multiple components in the same file. This is convenient when components are relatively small or tightly related to each other. If this file gets crowded, you can always move Profile to a separate file. You will learn how to do this shortly with imports.

Because the Profile components are rendered inside Gallery, Gallery is a parent component, rendering each Profile as a “child”. This is part of the magic of React: you can define a component once, and then use it in as many places and as many times as you like.

danger

Components can render other components, but you must never nest their definitions (No higher order functions!)

export default function Gallery() {
// 🔴 Never define a component inside another component!
// This is very slow and will cause bugs.
function Profile() {
// ...
}
// ...
}

Instead:

export default function Gallery() {
// ...
}

// ✅ Declare components at the top level
function Profile() {
// ...
}
Components all the way down

Most React apps nest components. This means that you won’t only use components for reusable pieces like buttons, but also for larger pieces like sidebars, lists, and ultimately, complete pages! Components are a handy way to organize UI code and markup, even if some of them are only used once.


Import and Export Components

As you nest more and more components, you will split them into different files to make them easy to scan, debug, and reuse.

So how will your components and files interact?

The root component file

In our first component, we made a Profile component and a Gallery component that renders it:

function Profile() {
return (
<img
src="https://elaineimagelink.jpg"
alt="Elaine"
/>
);
}

export default function Gallery() {
return (
<section>
<h1>Amazing scientists</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}

These currently live in a root component file, named App.js in this example. You can think of this as your landing screen, the first page you see when you load your application.

As you continue writing components, it will make sense to move your components, in this case Gallery and Profile out of the root component file. This will make them more modular and reusable in other files. You can move a component in three steps:

  1. Make a new javascript file to the components in. JS files are denoted by a .js suffix.
  2. Export your function component from that file (using either default or named exports).
  3. Import it in the file where you’ll use the component (using the corresponding technique for importing default or named exports).
Default vs named exports

There are two primary ways to export values with JavaScript: default exports and named exports. So far, our examples have only used default exports.

A file can have no more than one default export, but it can have as many named exports as you like.

React Export Structure

How you export your component dictates how you must import it. You will get an error if you try to import a default export the same way you would a named export! This chart can help you keep track:

SyntaxExport statementImport statement
Defaultexport default function Button() {}import Button from './Button.js';
Namedexport function Button() {}import { Button } from './Button.js';

People often use default exports if the file exports only one component, and use named exports if it exports multiple components and values.

// This is a default export
import Gallery from './Gallery.js'; //from './Gallery'; is equivalent

// This is a named export
import { Profile } from './Gallery';

export default function App() {
return (
<Gallery />
<Profile />
);
}