Learn React: Complete Roadmap
A structured learning path from JavaScript prerequisites to production-ready React apps. Built to avoid the most common mistakes: wrong order, outdated APIs, and tutorial hell.
study, coding, productivity
by Morris
JavaScript Prerequisites
React is a JavaScript library, not a replacement for JavaScript. These are the JS concepts that will trip you up inside React if you don't know them first.
- Master array methods: map, filter, reduce, find, some, every, flat
- Understand destructuring: object and array forms, with defaults and renaming
- Understand spread and rest operators in both objects and arrays
- Know ES modules: named exports, default exports, re-exports, and import aliases
- Understand closures and why they matter for hook behavior
- Know async/await and Promises: error handling, Promise.all, chaining
- Understand optional chaining (?.) and nullish coalescing (??)
- Know template literals and tagged template literals (used by styled-components if you ever use it)
- Verify your JS knowledge: build a small data manipulation script with no frameworks, no DOM
React Mental Model
Before writing a single component, understand what React actually is and why it works the way it does. The mental model prevents the confusion that comes later.
- Understand what React is: a library for building UIs by describing what they should look like, not how to update them
- Understand the virtual DOM: React maintains a lightweight copy of the DOM and diffs it to find the minimum changes needed
- Understand when React re-renders: state change, prop change, or parent re-render
- Read the 'Thinking in React' page on react.dev before writing any code
- Understand that React components are just functions that return JSX
- Understand one-way data flow: data flows down through props, events flow up through callbacks
Components and JSX
The syntax and structure of React. Straightforward once the mental model is in place.
- Set up a project with Vite and React (not Create React App, which is deprecated)
- Understand JSX: it compiles to React.createElement() calls, it is not HTML
- Write functional components and understand the naming convention (PascalCase)
- Pass and receive props: including destructuring in the function signature
- Use the children prop to build wrapper/layout components
- Implement conditional rendering: ternary operator, short-circuit &&, and early returns
- Render lists with .map() and always provide a stable, unique key prop
- Build a component that composes smaller components: a Card with Header, Body, and Footer subcomponents
State and Events
The first place React stops feeling like templates and starts feeling like a reactive system.
- Understand why you need useState: plain variables inside a component do not trigger re-renders
- Handle events: onClick, onChange, onSubmit, and understand synthetic events
- Build controlled inputs: form fields whose value is always driven by state
- Understand that state updates are asynchronous and batched
- Understand lifting state up: move shared state to the closest common ancestor of the components that need it
- Understand when NOT to use state: derived values should be computed during render, not stored in state
- Build a todo app from scratch: add, complete, delete, filter by status
Hooks Deep Dive
The hooks that separate React beginners from developers who can build anything.
- Understand useEffect: it runs after render to synchronize your component with something outside React
- Master the dependency array: understand what empty [], no array, and specific deps each mean
- Understand and fix the stale closure problem in useEffect
- Learn useRef: accessing DOM nodes directly and persisting values without triggering re-renders
- Learn useReducer for complex state logic: when useState with multiple related fields gets unwieldy
- Understand useCallback and useMemo: what they memoize, and when the cost exceeds the benefit
- Know the rules of hooks: only call at the top level, only call from React functions
- Build your first custom hook: extract repeated stateful logic into a reusable function
Component Patterns
How to structure components so they stay maintainable as an app grows.
- Recognize prop drilling and know when it is a problem (hint: it often is not)
- Learn the composition pattern: use children and render props to build flexible components
- Practice the compound component pattern: multiple components that share implicit state through Context
- Apply the single responsibility principle: if a component is hard to name, it is doing too much
- Understand controlled vs uncontrolled components in the context of reusable component APIs
- Decompose a complex UI from scratch: start from a wireframe and identify every component boundary before coding
Routing with React Router v6
Navigation and URL management in single-page applications. Use v6 only - the API changed significantly from v5.
- Install React Router v6 and understand why v5 tutorials will mislead you
- Set up BrowserRouter and define your route tree with nested routes
- Use Link and NavLink for navigation (NavLink adds an active class automatically)
- Use useParams to read dynamic URL segments like /users/:id
- Use useNavigate for programmatic navigation after form submission or authentication
- Implement nested routes: a layout component that renders child routes via Outlet
- Implement a 404 catch-all route with path="*"
- Build a protected route component that redirects unauthenticated users to login
State Management
Local state, shared state, and global state each have the right tool. Learn them in this order.
- Understand the decision tree: useState for local, lift state for shared, Context for low-frequency global, Zustand/RTK for high-frequency global
- Build a working Context: create a ThemeContext or AuthContext with createContext, a Provider, and a custom hook
- Understand why Context causes performance issues: every consumer re-renders when the context value changes
- Learn Zustand as a lightweight global store alternative
- Learn Redux Toolkit if your team or job uses Redux (skip raw Redux completely)
Data Fetching
Getting data from APIs, handling every state correctly, and graduating to a proper server-state library.
- Build a basic fetch pattern with useEffect: loading state, data state, error state
- Understand the race condition in useEffect data fetching and how to fix it with cleanup
- Install and configure TanStack Query (React Query)
- Use useQuery to fetch and cache data
- Use useMutation to handle POST, PUT, and DELETE requests with optimistic updates
- Understand cache invalidation: when to call queryClient.invalidateQueries after a mutation
- Build a paginated or infinite scroll list using useQuery or useInfiniteQuery
TypeScript with React
TypeScript adds a layer of friction that pays back tenfold in larger codebases. Learn it now, not after the habits are set.
- Create a new Vite project with the React + TypeScript template
- Type component props with interfaces or type aliases
- Use generics with useState when TypeScript cannot infer the type
- Type event handlers correctly: React.ChangeEvent, React.FormEvent, React.MouseEvent
- Type custom hook return values explicitly to get better autocomplete
- Understand React.FC vs plain function declarations for components (prefer plain functions)
- Migrate your todo app from the earlier section to TypeScript
Performance and Tooling
Measuring before optimizing. Most React performance problems are invisible until you look with the right tools.
- Install React DevTools browser extension and learn the Profiler tab
- Use React.memo to prevent a component from re-rendering when its props have not changed
- Lazy load routes and heavy components with React.lazy and Suspense
- Set up ESLint with the React Hooks plugin: it enforces the rules of hooks and the exhaustive-deps rule
- Write basic component tests with Vitest and React Testing Library
- Deploy a React app to Vercel or Netlify and understand build output: chunk splitting, asset hashing
- Understand useTransition and Suspense for concurrent features: mark non-urgent state updates to keep the UI responsive
Capstone Project
One real application that forces every concept to work together. No tutorials. Build something you would use.
- Choose a project with auth, multiple routes, real data fetching, CRUD operations, and at least one complex UI
- Plan the component tree and state architecture on paper before writing code
- Implement authentication using Firebase Auth, Supabase, or Clerk
- Build a full data layer: read, create, update, and delete with proper loading and error states for every operation
- Add at least one optimistic UI update: update the UI immediately before the server confirms
- Handle every error state visibly: failed fetches, validation errors, auth errors
- Add an error boundary to catch runtime errors and show a fallback instead of a blank screen
- Deploy to production and share the live URL
- Write a short README that explains: what the app does, the tech stack, architecture decisions, and what you would do differently