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
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:
- App.js
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 nameProfile
.
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 withsrc
andalt
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:
- App.js
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.
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:
- App.js
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:
- Make a new javascript file to the components in. JS files are denoted by a
.js
suffix. - Export your function component from that file (using either default or named exports).
- 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.
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:
Syntax | Export statement | Import statement |
---|---|---|
Default | export default function Button() {} | import Button from './Button.js'; |
Named | export 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.
- App.js
- Gallery.js
// 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 />
);
}
function Profile() {
return (
<img
src="https://i.imgur.com/QIrZWGIs.jpg"
alt="Alan L. Hart"
/>
);
}
export default function Gallery() {
return (
<section>
<h1>Amazing scientists</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}