Course
React
192 lessons across 18 modules
From JSX to production - components, state, forms, hooks, routing, data, performance, TypeScript, testing, and four projects that use the whole course. The road is laid out in full; lessons are being written one at a time.
React Fundamentals
JSX, rendering, and the shape of a React app
Prerequisite: the JavaScript course →Introduction to React
1What React is, what it is not, and the problem it was built for.
Why React?
2Declarative UI, component reuse, and what you give up for them.
React Application Structure
3Entry point, root render, and where a component tree begins.
Creating a React App with Vite
4Scaffolding, the dev server, and what the build actually produces.
JSX Fundamentals
5JSX is a function call in disguise - attributes, nesting, and self-closing tags.
JSX Expressions
6Embedding values with braces, and what JSX refuses to render.
Fragments
7Returning several elements without adding a wrapper div.
Conditional Rendering
8Ternaries, &&, and early returns - and when each one reads best.
Rendering Lists
9map() over data to produce elements, and handling the empty case.
Keys in React
10What a key is for, why the index is usually wrong, and what breaks without one.
Components and Props
Splitting a UI up, and passing data down
Functional Components
11A component is a function that returns UI. Everything else follows.
Props Basics
12Passing data from a parent component to a child - the thing that makes components reusable.
Props Destructuring & Default Props
13Destructuring, optional props, default values, rest and spread - and designing a clean component API.
Passing Functions as Props
14Callback props - how a child tells its parent that something happened.
Children Props
15children as the slot that makes wrappers possible.
A Modal that knows nothing about what it contains
Component Composition
16Building screens by nesting components instead of by adding options.
A Card that takes content rather than twelve boolean props
Creating Reusable Components
17Finding the right seam - what to make configurable and what to fix.
One Button that covers six variants without a prop explosion
Props vs State
18Read-only from above against owned and changeable here.
Deciding where a search term should live
Component Design Best Practices
19Size, naming, one responsibility, and when to stop splitting.
Reviewing a component that does three jobs
Module Project: Course Catalogue
20Components, props, children, and callbacks in one small app.
A course catalogue page built from typed, reusable components
State and Events
Making a component remember, and respond
Understanding State
21Why a plain variable does not survive a render, and what state fixes.
A counter with let, and the same one with state
useState
22Declaring state, reading it, and the setter that replaces it.
A search box that drives a filtered list
Updating Primitive State
23Strings, numbers, and booleans - and why updates are not immediate.
Logging state right after setting it and seeing the old value
Updating Objects
24Replacing rather than mutating, and spreading the rest.
Editing one field of a user form without losing the others
Updating Arrays
25Add, remove, and edit without push, splice, or sort.
A todo list where every operation returns a new array
Functional State Updates
26setCount(c => c + 1) and the stale-value bug it prevents.
Two increments in one handler, and why only one lands
Event Handling
27Attaching handlers, the synthetic event, and passing arguments.
Why onClick={handler()} fires on render
Mouse Events
28Click, double click, hover, and the difference between target and currentTarget.
A row click that ignores clicks on its delete button
Keyboard Events
29keydown against keyup, reading the key, and accessible shortcuts.
Submitting on Enter and closing on Escape
Form Events
30onChange, onSubmit, and preventDefault.
A login form that does not reload the page
State and Component Re-rendering
31What triggers a render, what it costs, and why it is not a redraw.
Counting renders with a console log to see what really happens
Forms
Controlled inputs, validation, and submission
Controlled Components
32React as the source of truth for an input, and the uncontrolled alternative.
An input that will not type until you wire onChange
Input Fields
33Text, number, email, password - value, onChange, and the types that lie.
Why a number input still gives you a string
Select and Checkbox
34value against checked, and multi-select.
A filter panel with a dropdown and three checkboxes
Radio Buttons
35Grouping by name, and one piece of state for the whole group.
Choosing a difficulty level
Multiple Form Fields
36One state object and one handler, keyed by input name.
A six-field profile form with a single onChange
Form Validation
37When to validate, where to keep errors, and how to show them.
Validating on blur and again on submit
Dynamic Forms
38Fields that appear, repeat, and are removed - and keeping keys stable.
Adding and removing question rows in a quiz builder
File Uploads
39The file input, FormData, previews, and size limits.
Uploading an avatar with a preview before submit
Form Submission
40Disabling during submit, handling failure, and not double-posting.
A submit button that cannot be clicked twice
Building a Complete Form
41Every piece together - state, validation, submit, error, and success.
A registration form from empty file to working
React Hooks
The built-in hooks, their rules, and writing your own
Every hook with a live demo →Understanding Hooks
42What a hook is, why they replaced classes, and how React tracks them.
Why hooks are stored by call order, not by name
Rules of Hooks
43Top level only, components and hooks only - and what breaks otherwise.
A hook inside an if, and the state that lands on the wrong variable
useEffect
44Running code after render, and what an effect is actually for.
Setting the document title when a lesson opens
Effect Dependencies
45The array, what belongs in it, and the two ways to get it wrong.
An empty array that captures a stale value
Effect Cleanup
46Returning a teardown, and why it runs more often than you expect.
A subscription that leaks until you clean it up
API Calls with useEffect
47Fetching on mount, tracking loading and error, and avoiding the race.
Two fast searches, and the slower response overwriting the newer one
useRef
48A value that survives renders without causing one, and DOM access.
Focusing an input on mount, and holding a timer id
useReducer
49Moving complex state transitions into one function.
A form with eight fields and four actions
useContext
50Reading shared values without threading props through every level.
A theme read three components deep
Custom Hooks
51Extracting stateful logic into a reusable function.
useDebounce and useLocalStorage, written from scratch
API Integration
Talking to a backend, and handling what comes back
Understanding REST APIs
52Methods, status codes, headers, and the contract a frontend depends on.
Reading an endpoint spec before writing any code
fetch
53The built-in client, and the ways it does not behave like you expect.
Why a 404 does not reject the promise
Axios
54Instances, interceptors, defaults - and when it earns its weight.
One instance carrying the base URL and auth header
GET Requests
55Reading data, query strings, and rendering the result.
A paginated course list
POST Requests
56Sending a body, setting headers, and using the response.
Creating a course and showing it without a refetch
PUT and PATCH Requests
57Full replacement against partial update, and which to send.
Editing one field without wiping the rest
DELETE Requests
58Removing a record, confirming first, and updating the list.
Deleting a row and rolling back when the server says no
Loading States
59Initial, refetching, and empty - three states people collapse into one.
A skeleton that does not flash on a fast response
Error Handling
60Network against HTTP against validation errors, and what to show for each.
A 422 with field errors mapped back onto the form
Request Cancellation
61AbortController, and cleaning up a request the user has moved on from.
Cancelling the previous search as the user keeps typing
Building an API Service Layer
62Keeping fetch calls out of components, in one typed place.
Moving twelve scattered calls into api/courses.ts
React Router
Multiple screens in a single-page app
Introduction to React Router
63What client-side routing is, and what it costs you for free.
A back button that stops working, and why
Routes
64Declaring paths, matching, and rendering the element.
Three screens behind three URLs
Links and Navigation
65Link against an anchor tag, and why one reloads the app.
Measuring the difference in the network tab
useNavigate
66Navigating from code after an action, and replace against push.
Redirecting to the new record after a successful save
Route Parameters
67Dynamic segments, reading them, and handling a bad one.
A lesson page keyed by slug
Query Parameters
68Putting filters in the URL so they survive a refresh and a share.
A filtered course list you can send to someone
Nested Routes
69Routes inside routes, and the Outlet that renders them.
A course page with tabs that are each a URL
Layout Routes
70Sharing a shell across screens without re-mounting it.
A sidebar that keeps its scroll position across navigations
Protected Routes
71Gating a screen on auth, and remembering where the user was going.
Logging in and landing back on the page you wanted
404 Pages
72The catch-all route, and the difference between missing and forbidden.
A useful not-found page rather than a blank screen
Lazy-loaded Routes
73Splitting by screen so the first load does not carry the whole app.
Cutting the initial bundle by moving the admin area behind lazy
State Management
When local state stops being enough
Redux in depth →Local State vs Global State
74The question to ask before reaching for any library.
Three pieces of state, and where each one belongs
Lifting State Up
75Moving state to the closest common parent, and the cost of doing it.
Two sibling components that need the same value
Prop Drilling
76What it is, when it is fine, and the point at which it is not.
A value passed through four components that ignore it
Context API
77Provider, consumer, and the re-render behaviour people miss.
A context change that re-renders half the app
When to Use Global State
78The honest criteria - and why most apps need less than they use.
Deleting a store that only one screen read from
Redux Fundamentals
79Store, action, reducer, dispatch - the model before the tooling.
The same counter in plain Redux
Redux Toolkit
80What it removes, and why nobody writes Redux by hand now.
The same counter, two thirds shorter
createSlice
81Reducers and actions together, with mutation that is not mutation.
Writing state.value += 1 safely, and how Immer allows it
useSelector
82Reading from the store, and selecting narrowly enough to avoid re-renders.
A selector returning a new object every time
useDispatch
83Sending actions, and keeping components free of store details.
A component that dispatches and knows nothing else
Async Redux Operations
84createAsyncThunk, and the three states every request has.
Pending, fulfilled, and rejected handled in one slice
RTK Query
85Treating the server as a cache rather than state you own.
Replacing a slice, a thunk, and three loading flags with one hook
Server State and TanStack Query
Caching, refetching, and data you do not own
Client State vs Server State
86The distinction that makes most state-management arguments dissolve.
Why a user list is not really your state
Introduction to TanStack Query
87What it does for you, and what it replaces.
Deleting a useEffect, two useStates, and a cleanup
Queries
88useQuery, its return shape, and reading status properly.
Loading, error, and data without writing any of the plumbing
Query Keys
89The cache identity - and why getting it wrong shows stale data.
Two searches sharing one key and one wrong result
Mutations
90Writes, their lifecycle, and what to do when they land.
Creating a course and refreshing the list automatically
Caching
91What is kept, for how long, and what a cache hit looks like.
Navigating back to a screen that renders instantly
Stale Time
92The single setting that decides how fresh your data feels.
The same screen at staleTime 0 and at five minutes
Refetching
93On focus, on reconnect, on interval - and turning them off.
A dashboard that updates when you come back to the tab
Query Invalidation
94Marking data stale after a write, and how wide to go.
Invalidating one list without refetching the whole app
Pagination
95Page-based data, and keeping the previous page visible.
Paging without the table collapsing between pages
Infinite Queries
96Cursor-based loading and an endless list.
Load more, and then the same thing on scroll
Optimistic Updates
97Showing the result before the server confirms - and rolling back.
A like button that reverts when the request fails
React Performance
Why it re-renders, and what to do about it
Understanding Re-rendering
98What causes a render, and why a render is not a repaint.
Counting renders before changing a single line
React Reconciliation
99How React decides what changed, and where keys fit in.
Watching a list update in the DOM inspector
Virtual DOM
100What it actually is, and the myths worth discarding.
Why "the virtual DOM is fast" is the wrong claim
React.memo
101Skipping a render when props are equal - and when that never happens.
A memo defeated by an inline object prop
useMemo
102Caching an expensive value, and the cost of caching a cheap one.
Measuring a filter before and after memoising it
useCallback
103A stable function identity, and why it only matters with memo.
A useCallback that does nothing because the child is not memoised
Avoiding Unnecessary Re-renders
104Composition, state placement, and fixing the cause not the symptom.
Moving state down instead of memoising three components
Code Splitting
105Shipping less on first load, and choosing the split points.
Reading the bundle analyser and finding the heavy import
lazy
106Deferring a component until it is needed.
A chart library that only loads on the reports tab
Suspense
107Declaring the fallback, and where to put the boundary.
One spinner in the right place instead of five
List Virtualization
108Rendering only what is on screen, for lists that are genuinely long.
Ten thousand rows that scroll smoothly
Web Workers
109Moving heavy work off the main thread so the UI keeps responding.
Parsing a large CSV without freezing the page
Advanced React
Boundaries, concurrency, and component patterns
Error Boundaries
110Catching a render error so one component does not blank the app.
A widget that fails without taking the page with it
Portals
111Rendering outside the parent DOM node, while staying in the tree.
A modal that escapes overflow hidden but keeps its context
Suspense
112Beyond lazy - coordinating loading states across a subtree.
Three components that appear together rather than one by one
Transitions
113Marking an update as interruptible so typing stays smooth.
A filter over a large list that no longer stutters
useTransition
114The pending flag, and showing that work is happening.
A tab switch that stays responsive while the next tab loads
useDeferredValue
115Letting one value lag behind on purpose.
An instant input with a deferred result list
Optimistic UI
116Rendering the intended result immediately, and correcting it.
useOptimistic on a comment form
Advanced Component Patterns
117Choosing a pattern from the problem rather than from fashion.
The same dropdown written four ways, compared honestly
Compound Components
118Related components sharing implicit state.
Tabs, TabList, and TabPanel that just work together
Render Props
119Passing rendering as a function - and what hooks replaced.
A Toggle that lets the caller decide the markup
Higher-Order Components
120Wrapping a component to add behaviour, and why it faded.
withAuth, and the custom hook that replaces it
Reusable Architecture Patterns
121Composing the patterns into something a team can maintain.
A component library seam that survives two years
TypeScript with React
Typing props, state, events, and data
TypeScript in depth →TypeScript Fundamentals
122The subset you need for React, without the full language tour.
Reading an error message and knowing what it wants
Typing Props
123Prop types, optional props, and defaults that type correctly.
A Button whose variant cannot be misspelled
Typing State
124Inference, and the cases where you must annotate.
useState with a null initial value
Typing Events
125Event types that are hard to guess and easy to look up.
ChangeEvent, MouseEvent, and FormEvent in one form
Typing Forms
126One type for the form shape, driving the state and the handler.
A field name that cannot be typed wrong
Typing useRef
127DOM refs against value refs, and the null that TypeScript insists on.
Why an input ref starts as null and how to narrow it
Typing useReducer
128A discriminated union of actions, checked exhaustively.
Adding an action and letting the compiler find every gap
Typing API Responses
129Where types come from, and why the network is not typed.
Validating at the boundary instead of trusting the cast
Interfaces vs Types
130The real differences, and a rule you can apply without thinking.
Declaration merging, and where it matters
Generics
131Writing something once that keeps its caller types.
A useFetch that returns the right shape each time
Generic Components
132Components parameterised by the data they render.
A Table that types its rows and its column keys together
Type-safe React Architecture
133Types at the seams so the rest of the app can relax.
One API type flowing from fetch to render
React Testing
Testing what the user does, not what the code is
Why Testing?
134What a test buys you, and the tests that buy nothing.
A test that breaks on every refactor and catches no bugs
Testing Fundamentals
135Arrange, act, assert - and what makes a test worth keeping.
Naming a test so a failure explains itself
Vitest and Jest
136Runner, matchers, and config - and how the two differ in practice.
A first passing test, run in watch mode
React Testing Library
137Querying by role and text, and why not by class name.
Rewriting a brittle selector as an accessible query
Testing Components
138Rendering, asserting on output, and staying off internals.
Testing what the card shows, not how it stores it
Testing Props
139Covering the variants that actually change behaviour.
One test per branch, not one per prop
Testing State
140Driving state through the UI rather than reaching into it.
Clicking to open a panel instead of setting a flag
Testing User Interactions
141userEvent, and why it beats firing raw events.
Typing that triggers the same handlers a real user would
Testing Forms
142Filling, submitting, and asserting on validation messages.
A submit blocked by an invalid email
Mocking APIs
143MSW at the network boundary rather than stubbing your own modules.
A test that survives swapping fetch for Axios
Testing Custom Hooks
144renderHook, and when a hook deserves its own test at all.
Testing useDebounce with fake timers
Integration Testing
145Several components together, which is where the bugs live.
Search, filter, and paginate in one test
Cypress E2E Testing
146The real browser, the real app - and how few of these you need.
One end-to-end test covering login to checkout
Authentication and Authorization
Who the user is, and what they may do
Authentication Concepts
147Authentication against authorization, sessions against tokens.
Drawing the flow before writing any of it
Login and Register
148The forms, the calls, and what to do with the result.
A login screen wired to a real endpoint
JWT
149What is inside a token, what it proves, and what it does not.
Decoding one, and why decoding is not verifying
Access Tokens
150Attaching them, expiring them, and keeping them short-lived.
An interceptor that adds the header once
Refresh Tokens
151Renewing silently, and the queue problem when several calls fail at once.
Three requests hitting a 401 and only one refresh going out
Cookie-based Authentication
152httpOnly cookies, SameSite, and why they beat localStorage.
The same login moved from localStorage to a cookie
Protected Routes
153Gating screens, and the flash of the wrong content before you do.
Rendering nothing until the session is known
Role-Based Access Control
154Roles on the client for UX, on the server for safety.
An admin link that hides but is still enforced server-side
Permission-Based UI
155Finer-grained than roles, and how to keep it readable.
A can() helper used across a toolbar
Logout
156Clearing state, clearing the cache, and ending the session properly.
Logging out without leaving the previous user cached
Session Handling
157Restoring on reload, expiry, and multiple tabs.
Logging out in one tab and having the other notice
React Security
The frontend half of keeping an app safe
XSS
158What React escapes for you, and the one prop that opts out.
dangerouslySetInnerHTML with untrusted content
CSRF
159Why cookie auth needs a token, and how SameSite changed it.
A forged form post, and the header that stops it
Secure Authentication
160The choices that matter most, ranked honestly.
Reviewing an auth flow for the three common holes
Token Storage
161localStorage, memory, and httpOnly cookies compared.
What each one exposes when an XSS lands
Input Sanitization
162Where sanitising belongs, and why the client is not enough.
Rendering user markdown without handing over the page
Dependency Security
163Audits, lockfiles, and the transitive packages you never chose.
Reading an npm audit report and deciding what is real
Environment Variables
164Everything in a frontend build is public. Everything.
Finding an API key in a production bundle
Secure API Communication
165HTTPS, CORS, and what CORS does not protect.
A CORS error, and why it is not a security feature for you
Common React Security Mistakes
166The handful that account for most real incidents.
A checklist applied to a finished app
React Architecture
Structuring an app that more than one person works on
React Project Structure
167By type against by feature, and why the first one stops scaling.
A components folder with ninety files in it
Feature-Based Architecture
168Grouping by what it does, with clear boundaries between features.
Moving one feature out without touching the others
Component Architecture
169Layers - page, container, presentational - and not over-applying them.
Deciding which of three components owns the fetch
Shared Components
170What earns a place in shared, and what should stay put.
A "shared" component used exactly once
Custom Hooks Architecture
171Organising hooks so they stay findable and testable.
Splitting a 200-line hook that does three things
API Service Architecture
172One place per resource, typed, with no fetch in a component.
Swapping the HTTP client without touching a screen
State Management Architecture
173Deciding per piece of state, and writing the decision down.
A one-page rule the whole team can follow
Error Handling Architecture
174Boundaries, toasts, and logging - one strategy, not per-component guesses.
Every failure path in an app, mapped
Configuration Management
175Environments, feature flags, and keeping config out of the code.
One build promoted through three environments
Scalable React Architecture
176The whole thing together, and what to do when it stops fitting.
Reviewing a real structure and naming what will break first
Production React
Building, shipping, and watching it run
Environment Configuration
177Per-environment values, and the ones that must never be in the bundle.
Three environments from one codebase
Development vs Production
178What changes in a production build, and the bugs that only appear there.
A double render in dev that is not a bug
Build Process
179What the bundler does, and how to read what it produced.
Following one import into the output file
Production Builds
180Minification, tree shaking, hashing, and cache headers.
A deploy that does not serve anyone a stale bundle
Error Logging
181Catching what users hit, with enough context to act on it.
A stack trace that means something after minification
Analytics
182Measuring use without collecting more than you need.
Three events that answer a real product question
Performance Monitoring
183Core Web Vitals from real users, not from your laptop.
Finding the slow route in field data
Accessibility
184Semantics, focus, and keyboard paths - the parts React will not do for you.
Navigating a whole flow without a mouse
Internationalization
185Extracting strings, plurals, dates, and layouts that grow.
A button that fits in English and breaks in German
SEO
186What a client-rendered app costs you, and the ways back.
Viewing source and finding an empty div
Deployment
187Static hosting, SPA rewrites, and the 404 on refresh.
A deep link that works only after you fix the rewrite
CI/CD
188Lint, typecheck, test, build, deploy - and failing fast.
A pipeline that blocks a broken build from shipping
React Projects
Four builds that use the whole course
Project 1 - Todo Application
189Components, state, forms, local storage, and filtering, end to end.
Add, complete, filter, and persist across a refresh
Project 2 - E-Commerce Application
190Products, search, filters, cart, authentication, and checkout.
A cart that survives login and reload
Project 3 - Admin Dashboard
191React, TypeScript, and Redux - users, roles, permissions, tables, and charts.
A paginated table with role-gated actions
Project 4 - Learning Platform
192Courses, modules, lessons, quizzes, progress, and learning paths.
The platform this course is hosted on, rebuilt