Skip to main content

Components

In this chapter, you learn about components, the basic unit of React.

What you'll learn in this chapter

  • What a component is and why you use it
  • How to write function components
  • Splitting and reusing components
  • Best practices for splitting files
info

This chapter uses the project you created in Chapter 3. Start the development server with npm run dev and study while writing code.

What is a component

A component is the UI divided into independent, reusable parts. You can define any UI element — buttons, forms, cards, and so on — as a component.

info

Why split the UI into components? The three main reasons are:

  1. Reusability: You can reuse the same UI part in multiple places
  2. Maintainability: The places that need changes are localized
  3. Readability: You can understand a large UI in small units

Function components

In today's React, function components are the standard.

function Greeting() {
return <h1>Hello!</h1>
}

You can also write them as arrow functions. *Arrow functions are explained in Chapter 2.

const Greeting = () => {
return <h1>Hello!</h1>
}
info

Don't use React.FC

To get ahead of the topic of type definitions: you sometimes see the style of attaching the type React.FC<Props> to a function component, but this book does not use it. Just specifying the type of the argument directly is enough, and React.FC has a few inconveniences.

// Recommended: specify the argument type directly
function Greeting({ name }: { name: string }) {
return <h1>Hello, {name}!</h1>
}

// Not recommended: React.FC
const Greeting: React.FC<{ name: string }> = ({ name }) => {
return <h1>Hello, {name}!</h1>
}

In the React official documentation and the TypeScript community, the style of not using React.FC has become mainstream in recent years.

Function components vs class components

Before React 16.8, "class components" were the mainstream, but with the arrival of Hooks (Chapter 7 onward), function components became the standard.

TypeCharacteristics
Function componentSimple, can use Hooks, the current standard
Class componentComplex, seen in legacy code

Class components are covered in Chapter 24, but use function components for new development.

Naming conventions for components

Component names are written in PascalCase (with an initial capital letter).

// OK: PascalCase
function UserProfile() { /* ... */ }
function ShoppingCart() { /* ... */ }

// NG: starting with lowercase (indistinguishable from HTML tags)
function userProfile() { /* ... */ }
warning

Component names that start with lowercase are interpreted as HTML tags. <button> is an HTML element, but <Button> is a React component. This difference is very important.

Using components

You use components like HTML tags.

function App() {
return (
<div>
<Greeting />
<Greeting />
</div>
)
}

Let's try it: create and use a component

Rewrite src/App.tsx as follows, defining a Greeting component and using it multiple times.

Hint
  1. Define a component with function Greeting()
  2. Place <Greeting /> multiple times in JSX
Answer and explanation
// src/App.tsx
import './App.css'

function Greeting() {
return <p>Hello!</p>
}

function App() {
return (
<div>
<h1>Greeting App</h1>
<Greeting />
<Greeting />
<Greeting />
</div>
)
}

export default App

You can reuse a component as many times as you like. If you place <Greeting /> three times, "Hello!" is displayed three times. This is the reusability of components.

Splitting components

By splitting a large component into smaller components, it becomes easier to manage.

Before splitting

function App() {
return (
<div>
<header>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
<main>
<h1>Welcome</h1>
<p>Site description...</p>
</main>
<footer>
<p>&copy; {new Date().getFullYear()} My Site</p>
</footer>
</div>
)
}

export default App

After splitting

function Header() {
return (
<header>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
)
}

function Main() {
return (
<main>
<h1>Welcome</h1>
<p>Site description...</p>
</main>
)
}

function Footer() {
return (
<footer>
<p>&copy; {new Date().getFullYear()} My Site</p>
</footer>
)
}

function App() {
return (
<div>
<Header />
<Main />
<Footer />
</div>
)
}

export default App

Splitting into files

You split components into separate files and use them via import/export.

src/
├── components/
│ ├── Header.tsx
│ ├── Main.tsx
│ └── Footer.tsx
└── App.tsx
// src/components/Header.tsx
export function Header() {
return (
<header>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
)
}
// src/App.tsx
import { Header } from './components/Header'
import { Main } from './components/Main'
import { Footer } from './components/Footer'

function App() {
return (
<div>
<Header />
<Main />
<Footer />
</div>
)
}

export default App

Let's try it: practice splitting into files

Split components into files with the following steps.

  1. Create src/components/Header.tsx and display the site title and navigation
  2. Create src/components/Footer.tsx and display the copyright
  3. Import and use them in src/App.tsx
Hint
  1. Define a function with export function Header() and place the title and navigation inside a <header> tag
  2. Define a function with export function Footer() and place the copyright inside a <footer> tag
  3. Import with import { Header } from './components/Header' and use it as <Header />
Answer and explanation

Header.tsx

// src/components/Header.tsx
export function Header() {
return (
<header>
<h1>My App</h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
)
}

By adding the export keyword, you can import it from other files.


Footer.tsx

// src/components/Footer.tsx
export function Footer() {
return (
<footer>
<p>&copy; {new Date().getFullYear()} My App. All rights reserved.</p>
</footer>
)
}

&copy; is an HTML entity that displays the © symbol.


App.tsx

// src/App.tsx
import './App.css'
import { Header } from './components/Header'
import { Footer } from './components/Footer'

function App() {
return (
<div>
<Header />
<main>
<h2>Welcome</h2>
<p>The main content goes here</p>
</main>
<Footer />
</div>
)
}

export default App

You specify import paths as relative paths (starting with ./). It's common to use components with a self-closing tag, <Header />.

Key points of component design

1. Single responsibility

Make each component have a single responsibility.

2. Reusability

Design components with an eye toward being usable generically.

3. Appropriate granularity

Split at an appropriate granularity — neither too fine nor too large.

info

There's no single correct answer for splitting components. Adjust to match the scale of the project and your team's policy.

When should you split a component?

Consider splitting in cases like these:

  • The same UI pattern appears two or more times → split for reuse
  • A single component exceeds 100 lines → split for readability
  • It has multiple responsibilities → split for single responsibility
  • It's hard to test → split for testability

Conversely, if you split too much, "props drilling" (passing props down through many layers) occurs, which can make things more complex instead. *The solution to props drilling is covered in Chapter 13 (useContext).

Summary

  • A component is the UI divided into reusable units
  • Function components are the current standard
  • Name them in PascalCase
  • Split files at an appropriate granularity

In the next chapter, you learn about Props, which pass data to components.