Course outline · 0% complete

0/29 lessons0%

Course overview →

The 'use client' boundary

lesson 3-2 · ~11 min · 8/29

Opting in

Here is the counter from the React course, ported to Next.js:

// app/like-button.js
"use client";

import { useState } from "react";

export default function LikeButton() {
  const [likes, setLikes] = useState(0);
  return (
    <button onClick={() => setLikes(likes + 1)}>
      ♥ {likes}
    </button>
  );
}

Decode it:

  • "use client" must be the first line of the file, before imports. It is a directive, not a function call.
  • Everything below it is exactly the React you already know.
  • Without the directive, the build fails: useState and onClick are not allowed in server components.

It marks a boundary, not one file

The rule that makes the directive matter: everything a client file imports becomes client code too, because the browser must be able to run the whole subtree that a client component renders. In that sense the directive is contagious in one direction — downward through imports. Picture the component tree. "use client" draws a line, and the whole subtree below that line ships to the browser.

That leads to the golden rule:

Put "use client" as low in the tree as possible, on the small interactive leaves (a button, a search box), not on whole pages.

Mark a page-level component as client and you drag every component it imports into the bundle, throwing away the zero-JS benefit of server components for that entire page.

Quiz

Where must the "use client" directive appear?

Problem

Spot the bug. This file has no "use client" directive: ```jsx // app/newsletter/page.js import { useState } from "react"; export default function Newsletter() { const [email, setEmail] = useState(""); return <input value={email} onChange={(e) => setEmail(e.target.value)} />; } ``` What one line fixes it? (write the line)

Code exercise · javascript

Automate the client/server decision (pure JavaScript, runnable here). Write needsUseClient(features): it receives an array of strings describing what a component uses (like ["useState", "props"]) and returns true if any of them is client-only. Treat these as client-only: useState, useEffect, onClick, onChange, localStorage, window. Everything else (props, fetch, async) is fine on the server.