Chapter 3: Components in React
Components in React — this is where React really starts to feel powerful and fun.
Today we’re going to cover:
- Functional vs Class components
- Creating and nesting components
- Component composition
- Exporting & importing components
I’ll explain everything slowly and clearly, like a patient teacher walking you through it step by step. We’ll use plenty of complete, runnable examples you can copy-paste into your Vite project right now.
1. Functional vs Class Components (2026 Reality)
In modern React (React 18 → React 19 in 2026), almost everyone uses functional components + Hooks.
Class components still exist and work perfectly, but they are considered legacy for new code.
| Aspect | Functional Components (Recommended 2026) | Class Components (Legacy / Special Cases) |
|---|---|---|
| Syntax | Plain JavaScript function | ES6 class that extends React.Component |
| State | useState, useReducer | this.state + this.setState() |
| Side effects / lifecycle | useEffect | componentDidMount, componentDidUpdate, componentWillUnmount etc. |
| Readability | Cleaner, shorter, less boilerplate | More verbose, this binding issues |
| Performance | Slightly better (no this overhead) | Similar in practice |
| Modern features | Full access to all new hooks & React 19 features | Cannot use hooks directly |
| Error Boundaries | Not natively (but can wrap class component) | Native support via componentDidCatch |
| When to use in 2026 | Almost everything — new code, libraries, apps | Only for error boundaries or very old codebases |
Official recommendation (React docs + community 2026): Use functional components for all new work. Class components are still supported forever (no plans to remove), but new features favor functions + hooks.
2. Creating Your First Components
Example 1: Simple Functional Component
Open your project → create a new file: src/components/Greeting.tsx
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Greeting.tsx function Greeting() { return ( <div> <h2>Hello! Welcome to React learning.</h2> <p>Building UIs one component at a time.</p> </div> ); } export default Greeting; |
Now use it in App.tsx:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// App.tsx import Greeting from './components/Greeting'; function App() { return ( <div style={{ padding: '20px', fontFamily: 'system-ui' }}> <h1>My First React App</h1> {/* Using the component */} <Greeting /> <Greeting /> {/* You can reuse it many times */} </div> ); } export default App; |
Key points:
- Component name starts with Capital letter (Greeting, not greeting)
- Returns JSX (or null, or a fragment)
- Can be called like a custom HTML tag
Example 2: Class Component (for comparison – don’t use for new code)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// OldClassGreeting.tsx (just to see) import React from 'react'; class OldClassGreeting extends React.Component { render() { return ( <div> <h2>This is a class component (old style)</h2> <p>Still works, but we prefer functions now.</p> </div> ); } } export default OldClassGreeting; |
You can still import and use it — but notice how much more code it takes.
3. Nesting Components (Parent → Child)
Components can contain other components — this is the heart of React.
Create two more files:
src/components/Header.tsx
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function Header() { return ( <header style={{ backgroundColor: '#646cff', color: 'white', padding: '16px', textAlign: 'center' }}> <h1>React Learning Journey</h1> <p>Chapter 3 - Components</p> </header> ); } export default Header; |
src/components/Footer.tsx
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function Footer() { return ( <footer style={{ backgroundColor: '#f0f0f0', padding: '16px', textAlign: 'center', marginTop: '40px' }}> <p>© 2026 - Learning React step by step</p> </footer> ); } export default Footer; |
Now nest them in App.tsx:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import Header from './components/Header'; import Footer from './components/Footer'; import Greeting from './components/Greeting'; function App() { return ( <div style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column' }}> <Header /> <main style={{ flex: 1, padding: '20px' }}> <Greeting /> <Greeting /> </main> <Footer /> </div> ); } export default App; |
Visual structure:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
App (root) ├── Header ├── main │ ├── Greeting │ └── Greeting └── Footer |
4. Component Composition (passing children + building blocks)
The real power: compose complex UIs from small pieces.
Create a reusable Card component:
src/components/Card.tsx
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
interface CardProps { title: string; children: React.ReactNode; // ← allows any JSX inside } function Card({ title, children }: CardProps) { return ( <div style={{ border: '1px solid #ddd', borderRadius: '8px', padding: '20px', margin: '20px 0', boxShadow: '0 2px 8px rgba(0,0,0,0.1)', maxWidth: '500px' }}> <h3 style={{ marginTop: 0, color: '#646cff' }}>{title}</h3> <div>{children}</div> {/* children appear here */} </div> ); } export default Card; |
Now use composition in App.tsx:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import Card from './components/Card'; import Header from './components/Header'; import Footer from './components/Footer'; function App() { return ( <> <Header /> <div style={{ padding: '20px', maxWidth: '800px', margin: '0 auto' }}> <Card title="Welcome Message"> <p>This is inside a Card component.</p> <button style={{ padding: '8px 16px', background: '#646cff', color: 'white', border: 'none', borderRadius: '4px' }}> Click me </button> </Card> <Card title="Quick Tip"> <ul> <li>Components are reusable</li> <li>Start names with Capital letter</li> <li>Use composition to build complex UIs</li> </ul> </Card> <Card title="Your Progress"> <p>You have completed:</p> <ul> <li>Chapter 1: Introduction</li> <li>Chapter 2: JSX Basics</li> <li>Chapter 3: Components (current)</li> </ul> </Card> </div> <Footer /> </> ); } export default App; |
5. Exporting & Importing Components
| Export style | Syntax (in component file) | Import syntax (in another file) | Best for |
|---|---|---|---|
| Default export (most common) | export default MyComponent; | import MyComponent from ‘./MyComponent’; | Main/primary component |
| Named export | export function MyComponent() {} | import { MyComponent } from ‘./MyComponent’; | Multiple utilities/components |
| Named + default | export default MyComponent; export function Helper() {} | import MyComp, { Helper } from ‘./file’; | Mixed usage |
Common mistake to avoid:
|
0 1 2 3 4 5 6 7 8 9 10 |
// Wrong: lowercase first letter function greeting() { ... } // → React treats it as HTML tag → error // Correct: function Greeting() { ... } |
Summary – Chapter 3 Key Takeaways
- Prefer functional components + hooks in 2026 (cleaner, modern, future-proof)
- Class components → only for error boundaries or legacy code
- Components = functions returning JSX
- Capital letter for component names
- Nesting = putting components inside others
- Composition = building complex UIs from small reusable pieces (children prop is powerful)
- Use default exports for main components
Common Mistakes Section
- Writing component name in lowercase → React thinks it’s HTML tag
- Forgetting to export default → “Module not found” error
- Putting statements (if, for) directly in JSX → use ternary / && instead
- Mutating props inside component → props are read-only
Homework Suggestion
- Create 3–4 small components:
- ProfileCard (with name, photo placeholder, bio)
- SkillList (takes array of skills via props)
- Button (custom button with color prop)
- Compose them inside a new ProfilePage component
- Import and use ProfilePage in App.tsx
- Try both default and named exports in one file and import them correctly
Let me know:
- Any part unclear?
- Want to see props next (Chapter 4)?
- Want help debugging your homework?
You’re making excellent progress — keep going!
