Server and Client Components: Understand the Boundary
Server and Client Components: Understand the Boundary
A school report needs server-only data access and an interactive attendance button. Shipping database credentials to the browser would be wrong, but rendering only server content would not provide the button’s stateful interaction.
In an environment that supports React Server Components, server components run outside the client bundle, while client components support browser interactivity and client Hooks. The server/client boundary is supplied by an appropriate framework or integration; it is not enabled by adding React to a plain Vite page.
Understand
Distinguish server data work from browser interaction.
Build
Recognize use client as a module boundary directive.
Check
Keep secrets and authorization on the server.
Server data crosses a deliberate client boundary
Server
Obtain permitted school report data.
Boundary
Pass supported serializable props.
Client
Use state and event handlers for interaction.
Server rendering and Server Components are different ideas
Server-side rendering produces initial HTML. Server Components additionally allow component work to stay outside the client JavaScript bundle, with a framework-managed representation composed with client components. They are related technologies, but an app can server-render ordinary client-capable components without implementing Server Components.
A use client directive at the top of a supported module marks a client boundary and its transitive client dependencies. Client components can still contribute server-rendered initial HTML in a supporting framework. The directive does not mean that every part of rendering happens only in the browser. Server components cannot use browser state Hooks or event handlers directly.
Understand the client-side interactive piece first
This standalone browser App is the client interaction that could be placed behind a server/client boundary. It receives a fixed public name in this demo and manages local attendance state. It does not perform server rendering or access a database merely because it is called a React component.
React · JavaScript with JSX
import { useState } from 'react';
function AttendanceButton({ name }) {
const [present, setPresent] = useState(false);
return <section><p>{name}: {present ? 'present' : 'absent'}</p>
<button onClick={() => setPresent(value => !value)}>Toggle attendance</button></section>;
}
export default function App() {
return <main><h1>Client attendance interaction</h1><AttendanceButton name="Maya" /></main>;
}Expected screen and behavior
The local browser component shows Maya absent; Toggle attendance changes only its local display.Follow data ownership across the boundary
React · Understand the client-side interactive piece first
import { useState } from 'react';
function AttendanceButton({ name }) {
const [present, setPresent] = useState(false);
return <section><p>{name}: {present ? 'present' : 'absent'}</p>
<button onClick={() => setPresent(value => !value)}>Toggle attendance</button></section>;
}
export default function App() {
return <main><h1>Client attendance interaction</h1><AttendanceButton name="Maya" /></main>;
}In the runnable example, App and AttendanceButton both run as ordinary client components. React state is stored in AttendanceButton. The click updates its local value and describes the next screen. No secret or server API is involved.
In a Server Components framework, a server parent could obtain a permitted public name and pass it into the client boundary. Only data suitable for that boundary should cross it. Authorization must determine whether the user can receive the report, rather than relying on hiding a browser button.
Read actual framework files without pretending they run here
The two files below illustrate a supported Server Components integration. SchoolPage is an async server component producing a public name; AttendanceButton is a client module. A real database operation would replace the explicit local server fixture only after its server permissions and contract are implemented. This pair requires a framework with Server Components support; it is not an ordinary App.jsx pair in a plain Vite app.
Server file SchoolPage.jsx:
import AttendanceButton from "./AttendanceButton.jsx";
export default async function SchoolPage() {
const student = await Promise.resolve({ name: "Maya" });
return <AttendanceButton name={student.name} />;
}Client file AttendanceButton.jsx:
"use client";
import { useState } from "react";
export default function AttendanceButton({ name }) {
const [present, setPresent] = useState(false);
return <button onClick={() => setPresent(value => !value)}>
{name}: {present ? "present" : "absent"}
</button>;
}Try the school task
React · starting example
import { useState } from 'react';
function AttendanceButton({ name }) {
const [present, setPresent] = useState(false);
return <section><p>{name}: {present ? 'present' : 'absent'}</p>
<button onClick={() => setPresent(value => !value)}>Toggle attendance</button></section>;
}
export default function App() {
return <main><h1>Client attendance interaction</h1><AttendanceButton name="Maya" /></main>;
}Build the client part for a report with name and total props. Keep a show-details toggle local while leaving the report values read-only.
Worked answer
The client component reads its supplied public values and owns only whether details are shown. This is runnable in a browser project; it does not imply that the fixed fixture was fetched securely from a real server.
React · JavaScript with JSX
import { useState } from 'react';
function Report({ name, total }) {
const [show, setShow] = useState(false);
return <section><h2>{name}</h2><button onClick={() => setShow(value => !value)}>Toggle details</button>
<p>{show ? 'Total: ' + total : 'Details hidden'}</p></section>;
}
export default function App() {
return <main><h1>Client report fixture</h1><Report name="Maya" total={75} /></main>;
}Expected screen and behavior
Toggle details displays Total: 75 from read-only props.Mistakes and boundaries
use server marks supported Server Functions, not a universal instruction making any component a server component. Server Functions can be invoked from client code through framework machinery, so validate arguments and authorize each action on the server.
Boundary values must meet React’s supported serialization contract. Do not pass arbitrary database handles or secret-bearing objects to a client component.
Framework bundler integration and deployment support matter. Server Components tooling interfaces may change between releases; follow the selected framework’s supported versions.
Check your reasoning
React · Understand the client-side interactive piece first
import { useState } from 'react';
function AttendanceButton({ name }) {
const [present, setPresent] = useState(false);
return <section><p>{name}: {present ? 'present' : 'absent'}</p>
<button onClick={() => setPresent(value => !value)}>Toggle attendance</button></section>;
}
export default function App() {
return <main><h1>Client attendance interaction</h1><AttendanceButton name="Maya" /></main>;
}Choose the answer that follows the data and the interaction, then read the explanation for each alternative.
Carry the idea forward
Assign server data and client interaction deliberate responsibilities. Review client data requests and runtime-specific deployment.
Read the primary reference: React: Server Components and integration boundaries.
Reaching the recap and completing the quizzes are separate milestones.