MERN Course: React Essentials
Weeks 10–13 of the MERN syllabus — components, hooks, routing, API fetching, Context, Zustand, testing with RTL, and capstone project guidance.
Introduction
React is the front-end pillar of MERN. This post completes the React Essentials syllabus with production patterns — including the same MDX blog system this site uses.
Course Reference
Quick index
| # | Topic | Description |
|---|---|---|
| 1 | Getting Started with React | React builds UIs from composable components. |
| 2 | Components, Props, and State | Props flow down; state is local unless lifted or stored globally. |
| 3 | Lists, Conditional Rendering & useEffect | Lists need stable key props (prefer IDs over array index). |
| 4 | Event Handling and Forms | Controlled inputs bind value to state and onChange to update it. |
| 5 | Styling React Components | Options: CSS Modules (scoped classes), Tailwind utilities, CSS-in-JS (styled-components). |
| 6 | React Router & Protected Routes | SPAs swap views without full page reloads. |
| 7 | Fetching Data from APIs | Show loading and error UI for every async request. |
| 8 | Advanced Hooks & Context API | useReducer for complex state, useContext to avoid prop drilling, useMemo/useCallback to stabilize references for memoized children.. |
| 9 | Redux & Zustand | Global state stores shared data: cart, auth user, UI flags. |
| 10 | Testing React Components | React Testing Library queries how users interact (roles, labels). |
| 11 | Final React Project | Capstone: plan scope, pick state strategy (local → Context → Zustand), integrate an API, add tests for critical paths, deploy to Vercel.. |
Week 10: React Fundamentals
1. Getting Started with React
React builds UIs from composable components. JSX is syntax sugar for React.createElement. In 2026, use Vite or Next.js instead of deprecated Create React App for new projects.
Example:
function Welcome({ name }) {
return <h1>Hello, {name}</h1>
}
export default function App() {
return (
<main>
<Welcome name="MERN Developer" />
</main>
)
}2. Components, Props, and State
Props flow down; state is local unless lifted or stored globally. useState returns current value and updater — updater can accept a function for prev state.
Example:
'use client'
import { useState } from 'react'
export function Counter({ step = 1 }) {
const [count, setCount] = useState(0)
return <button onClick={() => setCount((c) => c + step)}>Count: {count}</button>
}3. Lists, Conditional Rendering & useEffect
Lists need stable key props (prefer IDs over array index). useEffect runs after paint — ideal for fetch, subscriptions, and syncing with localStorage.
Example:
useEffect(() => {
const saved = localStorage.getItem('tasks')
if (saved) setTasks(JSON.parse(saved))
}, [])
useEffect(() => {
localStorage.setItem('tasks', JSON.stringify(tasks))
}, [tasks])Week 11: Events, Forms, Styling & Routing
4. Event Handling and Forms
Controlled inputs bind value to state and onChange to update it. Validation runs on blur, submit, or debounced input.
Example:
const [email, setEmail] = useState('')
const [error, setError] = useState('')
function handleSubmit(e) {
e.preventDefault()
if (!email.includes('@')) {
setError('Invalid email')
return
}
submitForm({ email })
}5. Styling React Components
Options: CSS Modules (scoped classes), Tailwind utilities, CSS-in-JS (styled-components). This portfolio uses Tailwind + CSS modules for demos.
Example:
import styles from './Card.module.css'
export function Card({ title, children }) {
return (
<article className={styles.card}>
<h2>{title}</h2>
{children}
</article>
)
}6. React Router & Protected Routes
SPAs swap views without full page reloads. Protect routes by checking auth state and redirecting to login.
Example:
import { Navigate, Route, Routes } from 'react-router-dom'
function ProtectedRoute({ user, children }) {
if (!user) return <Navigate to="/login" replace />
return children
}Week 12: APIs, Hooks & State Management
7. Fetching Data from APIs
Show loading and error UI for every async request. Abort in-flight fetches when component unmounts or deps change.
Example:
useEffect(() => {
const controller = new AbortController()
setLoading(true)
fetch('/api/posts', { signal: controller.signal })
.then((r) => r.json())
.then(setPosts)
.catch((err) => {
if (err.name !== 'AbortError') setError(err.message)
})
.finally(() => setLoading(false))
return () => controller.abort()
}, [])8. Advanced Hooks & Context API
useReducer for complex state, useContext to avoid prop drilling, useMemo/useCallback to stabilize references for memoized children.
9. Redux & Zustand
Global state stores shared data: cart, auth user, UI flags. Redux is verbose but predictable; Zustand is minimal and hook-friendly.
Example:
import { create } from 'zustand'
const useTaskStore = create((set) => ({
tasks: [],
addTask: (title) =>
set((state) => ({
tasks: [...state.tasks, { id: crypto.randomUUID(), title, done: false }],
})),
}))Week 13: Testing & Final Project
10. Testing React Components
React Testing Library queries how users interact (roles, labels). Test visible behavior, not internal state.
Example:
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Counter } from './Counter'
test('increments on click', async () => {
render(<Counter />)
await userEvent.click(screen.getByRole('button'))
expect(screen.getByText(/count: 1/i)).toBeInTheDocument()
})11. Final React Project
Capstone: plan scope, pick state strategy (local → Context → Zustand), integrate an API, add tests for critical paths, deploy to Vercel.
- Define MVP features before coding — todo app, blog CMS, or dashboard
- Use folder structure:
components/,hooks/,lib/,types/ - Run Lighthouse before demo — fix accessibility and performance regressions
Subscribe to my newsletter
Stay up to date and get notified when I share new contents.
No spam ever, unsubscribe anytime