Loading video...

Video Failed to Load

Go Home

React Server Components allow you to call your database directly from a component. And that's great... but how do we make sure this code never ever runs on the client?

177,038 views • 2 years ago •via X (Twitter)

10 Comments

Lee Robinson's profile picture
Lee Robinson2 years ago

"Wait, is this a Next.js feature?" Nope — this is for usage with any React server framework.

David K 🎹's profile picture
David K 🎹2 years ago

Love the video Don't love the fact that you have to install another package and opt-in to this major footgun defender

Alex Moldovan is on 🦋's profile picture
Alex Moldovan is on 🦋2 years ago

This makes sense as a protection layer, but isn't it just a self-inflicted problem in the first place? Shouldn't the framework protect the developers from mistakes instead of requiring you to know this workaround?

Lee Robinson's profile picture
Lee Robinson2 years ago

It helps to work backwards from the ideal DX: what if you didn't have to write anything, and the framework could just magically figure everything out for you? And then look at reality. We need some sort of signal to tell the compiler the environment the code runs in. Ideally we don't want to add these checks in every single file. And ideally it wouldn't be something specific to one framework. Instead, you want a standard for the ecosystem (whether Next or other frameworks). A single line to enforce either "server-only" or "client-only". It's not auto-magical but some explicitness is a feature and not a bug. It's an adjustment though because most apps have completely separate frontend and backend words, and this model pairs well when building a "data access layer" inside of a fullstack app.

Lee Robinson's profile picture
Lee Robinson2 years ago

If you want to learn more, this post goes in much more detail on security in Next.js.

Dailos R. DÍAZ LARA 🦋's profile picture
Dailos R. DÍAZ LARA 🦋2 years ago

IMHO a component never should call a database directly. I don’t mind if it’s a server component. Why we don’t call the database endpoint directly from a client? Cos it’s a security breach. Technology go ahead fast but it doesn’t mean that we should forget foundations.

Lee Robinson's profile picture
Lee Robinson2 years ago

More often, you're likely calling a "data access layer" where you co-locate your backend logic.

Daniel Nagy's profile picture
Daniel Nagy2 years ago

Decent workaround but importing a module to guard against code running in the wrong environment is not great.

Anthony Holmes's profile picture
Anthony Holmes2 years ago

This is great but now we have use client, use server, and this? I can see this being very confusing

Lee Robinson's profile picture
Lee Robinson2 years ago

I like the framing here personally!

Related Videos

How should you search, filter, and paginate data with Next.js? This demo has 50,000 books in a Postgres database. • Page Load: When the page loads, we see the React Suspense fallback. This loading skeleton is displayed until the first page of books is retrieved from the database. • Searching: The search input has a 200ms debounce. After 200ms of inactivity, the form submits, updating the URL state with `?q={search}`. The Server Component reads `searchParams` and queries the database. On form submission, a React transition starts, allowing us to read the pending status with `useFormStatus` to display an inline loading state. • State Preservation: Navigating to an individual book page retains the search input state. Reloading the page or sharing the link preserves the search results. • Client-side Filtering: Filtering authors in the left sidebar is done client-side. Authors are fetched by a Server Component and passed as props to the sidebar. Changing the input value updates React state and re-renders the sidebar. • Optimistic Updates: The sidebar’s selected authors are optimistically updated with `useOptimistic`. Checkbox selections update instantly without waiting for the URL to change. • State Preservation: Navigating to an individual book page retains the sidebar filter input and selected author state across navigations, giving it an app-like feel. • Pagination: Navigating between pages updates the URL state, triggering the Server Component to query the database for the specific page of books. We also fetch the total book count to show the total number of pages. This demo isn't perfect yet (still working on it) but it's been a fun playground for some of these patterns. You can imagine a similar experience for thousands of movies, cars, products, or any other very large dataset. Demo → Code →

Lee Robinson

236,802 views • 2 years ago