Course outline · 0% complete

0/29 lessons0%

Course overview →

What React alone doesn't give you

lesson 1-1 · ~10 min · 1/29

The gap after the React course

In the React course you built components, wired up state with useState, and fetched data in useEffect. That knowledge is the foundation of this whole course. But React itself is deliberately small. It is a view library: it turns state into UI and keeps the two in sync. Everything else about a real website is left to you.

Look back at those React apps and four gaps stand out:

  • Routing. You probably rendered one page, or bolted on a router library.
  • Server rendering. The browser got an empty <div id="root"> and waited for JavaScript.
  • Data fetching conventions. Every team invents its own useEffect plus loading-flag dance.
  • Production plumbing. Code splitting (breaking your JavaScript into per-page chunks so visiting one page does not download the code for the whole app), image optimization, caching, deployment.

None of these are React's job. React solves exactly one problem, and solves it well: turn application state into UI, then update that UI efficiently when the state changes. Routing, server rendering, and image optimization are production concerns that React deliberately leaves to a framework.

Why the empty div hurts

A plain React app (a single-page application, or SPA) ships one HTML file that is almost empty:

<body>
  <div id="root"></div>
  <script src="/bundle.js"></script>
</body>

The user's browser downloads the JavaScript bundle, runs it, and only then does React draw the page. Two costs follow:

  1. Slow first paint. On a cheap phone with weak Wi-Fi, users stare at a blank screen.
  2. Weak SEO. Search-engine optimization is how easily search engines like Google can read and rank your pages, which decides how much free traffic finds your site. Crawlers and link previews often read only the raw HTML. An empty div tells them nothing about your content.

What a crawler actually sees on an SPA

Suppose a search crawler that reads only the initial HTML loads a plain React SPA. It receives an almost-empty HTML file: one root div plus a script tag, and nothing else. In a classic SPA that shell is the entire server response. All the real content, the headings, the copy, the product names, appears only after the browser downloads and runs the JavaScript bundle, and a simple crawler never does that. As far as the crawler is concerned, the page has no content at all.

You already built the other half

In Backend with Node.js you wrote Express servers: routes like app.get("/posts/:id"), JSON APIs, middleware, environment variables. So you have actually met both halves of a production web app, a rendering layer (React) and a server layer (Express), as separate projects that talk over HTTP.

A framework's pitch is simple: one project that gives you both halves, with the wiring already done. Routing that comes from your file names. Components that can run on the server and touch data directly. One npm run build that outputs a deployable app. That is exactly what Next.js is, and it is why the official React docs recommend starting new apps with a framework.

Dividing the work: React's job and the framework's job

It is worth being precise about the split, because it explains every design decision in the rest of this course.

ConcernWho owns it
Turning state into UI, updating it efficientlyReact
Component model, JSX, props, hooksReact
Mapping URLs to pagesThe framework
Rendering HTML on the serverThe framework
Data fetching conventionsThe framework
Code splitting, image optimization, cachingThe framework
Build output and deploymentThe framework

React is a view library: state in, UI out. Everything in the right-hand column is a production concern that React leaves to frameworks like Next.js.

Code splitting, concretely

Picture an app with 40 pages and code splitting set up. A visitor lands on /about. Their browser downloads two things: the shared framework code that every page needs (React itself, your root layout), plus the single chunk for /about.

The other 39 pages' JavaScript never travels over the network. That is what code splitting means: the bundler breaks your app's JavaScript into per-page chunks so a visitor pays only for the page they are on, plus the shared core.

Doing this by hand means writing bundler configuration. Next.js does it automatically, per route, with no setup. That is exactly the kind of production plumbing this course is about.