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
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.
Why split the UI into components? The three main reasons are:
- Reusability: You can reuse the same UI part in multiple places
- Maintainability: The places that need changes are localized
- 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>
}
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.
| Type | Characteristics |
|---|---|
| Function component | Simple, can use Hooks, the current standard |
| Class component | Complex, 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() { /* ... */ }
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
- Define a component with
function Greeting() - 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>© {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>© {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.
- Create
src/components/Header.tsxand display the site title and navigation - Create
src/components/Footer.tsxand display the copyright - Import and use them in
src/App.tsx
Hint
- Define a function with
export function Header()and place the title and navigation inside a<header>tag - Define a function with
export function Footer()and place the copyright inside a<footer>tag - 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>© {new Date().getFullYear()} My App. All rights reserved.</p>
</footer>
)
}
© 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.
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.