Skip to Content
All posts

React Server Components: Separating Hype from Reality

 — #React#Server Components#Next.js#Web Development

When React Server Components first arrived, I was skeptical. "Is this just going backwards?" I thought. "Aren't we supposed to have the freedom of client-side rendering?"

Six months into working with them, I've realized how much I had it backwards.

The Core Misconception

Most of us grew up thinking: JavaScript frameworks live on the client. That's the whole point.

React Server Components flip this (slightly) by saying: Some things don't need to be JavaScript at all. And that's actually profound.

The misconception I see most often: "RSCs mean we're ditching client-side React."

Reality: RSCs let you use React syntax server-side to produce less JavaScript sent to the client. Your interactive components still run client-side. You just get to choose what needs to be interactive.

Why This Actually Matters

Think about a typical dashboard. You have:

  • A data table (doesn't need to be interactive)
  • A filter sidebar (absolutely needs interactivity)
  • A header with real-time notifications (needs interactivity)

Pre-RSCs, we'd either:

  1. Send the entire thing as client JS and pay the bundle cost
  2. Render it server-side and lose the ability to use your component framework

With RSCs, you render the table server-side (no JS needed), make the sidebar and header Client Components, and everyone wins. The client gets less JavaScript. Your components stay composable. Your data fetching is straightforward.

The "Feels Weird" Part

Yeah, async components feel strange at first:

async function PostList() {
  const posts = await fetch('https://api.example.com/posts');
  return (
    <ul>
      {posts.map(post => <li key={post.id}>{post.title}</li>)}
    </ul>
  );
}

But think about it: this is just... normal server code. It's familiar. No more useState hooks for loading states that could've just been fetched upfront. No useEffect dancing around data fetching.

The mind-shift: You're not writing "server code" and "client code" anymore. You're writing React. The framework figures out where it runs.

The Real Gotcha

The part nobody talks about: state management becomes more interesting.

If your Server Component fetches data and passes it as a prop to a Client Component that modifies it... you need a way to refetch or update that data. That's where mutations (server actions) come in. And yeah, that takes getting used to.

But once you do? You realize you've eliminated an entire class of bugs. No more "stale data on the client" problems. Your server is still the source of truth. You're just being smarter about what computation lives where.

The Honest Take

RSCs aren't a silver bullet. You don't need them for every app. A highly interactive dashboard with tons of real-time updates? Maybe stick with a traditional client-heavy approach.

But for content-rich applications, product pages, dashboards with mostly-static sections? RSCs are a genuine quality-of-life improvement. Smaller bundles. Simpler component logic. Less JavaScript to ship.

And honestly, that's pretty cool.

The future probably isn't "everything server" or "everything client." It's thoughtful about what goes where. RSCs are just giving you better tools to be thoughtful about it.