Intermediate React, v6

React Server Components Overview

Intermediate React, v6

Lesson Description

The "React Server Components Overview" Lesson is part of the full, Intermediate React, v6 course featured in this preview video. Here's what you'd learn in this lesson:

Brian introduces React Server Components (RSCs), which render exclusively on the server and maintain a connection with the app, unlike SSR, which only speeds up the initial load. RSCs allow for server-side code execution, such as making SQL queries, without sending the code to the client.

Preview
Close

Transcript from the "React Server Components Overview" Lesson

[00:00:00]
>> Brian Holt: Okay, so we have gotten through static site generation, server-side rendering, and now we are fully into this unknown new territory, which is React server components. I reflexively call them RSCs, I'm trying to at least sprinkle in continually that they are React server components, but if I say RSCs, that's what I mean.

[00:00:25]
So we've talked about client-side components, we talked about SSG, we talked about SSR. But now we're gonna talk about React server components, which are relatively new concepts. It's probably why most of you are interested in taking this course, it's the most interesting new thing about this course. Let's just dwell a second on this statement right here, because I think it's surprising to some people, it was surprising to me.

[00:00:50]
I heard about RSCs the first time, I was at Next Conf, forever ago, and I was like, they're redoing server side rendering, interesting, right? And once I got more and more into that, I realized that they're actually entirely different concepts. You can do RSCs with SSR, you can do one, you can not do the other, you can do both, and you can do neither.

[00:01:16]
So we'd just say they don't really have too much to do with each other. The key is with server-side rendering, you do the initial page load, you send that down to the user, and then everything gets taken over by client-side rendering, that's SSR, right? React server components are just components that only ever render on the server.

[00:01:35]
So it's actually an ongoing relationship between the server and the app. Whereas SSR, once it does its initial render, it's just done, it's no longer involved in the equation, client-side react takes over at that point. So SSR only speeds up that first page, that's full stop, that's all it does ever, or it'll ever do.

[00:01:55]
RSCs are much more opinionated, much more integrated with your server, it's why you need something like Next.js because it just won't work on a Fastify server. Despite the fact that we're actually going to make it work with the Fastify server, but we're not supposed to. [LAUGH] So does that make sense?

[00:02:15]
They're different, so you can have server-side rendering where you output everything for that first page render. And then you can have RSCs after that where you have an ongoing relationship between your app both on the server and on the client. Or you cannot, you can just say, here's the first page load client-side react to take over, or you can not do server-side rendering and then you can have RSCs after that fact.

[00:02:41]
All this to say is they don't have anything to do with each other, from that perspective. So an RSC it's just really this, it's just a server component that only renders on the server and then you're also gonna have client components by virtue of that only ever do anything on the client as well.

[00:02:58]
That's really it, but the cool thing about a React server component is, the client actually never receives any of the code of what happens on the server, why is that cool? Now you can start making SQL queries in your React components, because it's all on the server, right?

[00:03:14]
And I know that's a little weird, if it doesn't feel weird you haven't been writing React long enough. But to do an effect essentially that directly just queries your database should feel a little strange but it's fine because it's all happening on the server. And then all that gets sent down at the end of it, it's not a React component at all, it's just mark-up.

[00:03:37]
Or it's React flight protocol we're gonna get there, but for all intents and purposes, it's just a condensed HTML, is really what ends up getting sent over the wire. So, why did we do this, why are we here, why are you listening to me? These are all questions I have no answers for.

[00:04:00]
But no matter what you do with React, large swaths of your app are going to be just mark-up, just stuff, right? Stuff that doesn't have any sort of interactivity. Let's talk about just this body, right, this is a React app, there's nothing interactive about this body component in here, right?

[00:04:22]
It's just reading from a markdown file and displaying you a bunch of mark-up, it's inert, right, it doesn't do anything, it just displays, it just is. Now, if this was a client-side React app, which it very well could have been, right? This would still exist in React code, right?

[00:04:39]
It would still be wired up to be interactive even if it could never be interactive. And that's what React server components kind of like lean into that idea. It's like, look, most of this is never interactive, let's just simplify that aspect of it and just say this is just gonna be rendered on the server and then it's just never going to change after that, so it has no interactivity afterwards.

[00:05:03]
Yeah, Mark.
>> Mark: A clarification from chat, so essentially it reduces the hydration step.
>> Brian Holt: So, at best I can say the answer is it changes the relationship to hydration, [LAUGH] it's just different. Or maybe stated differently, your framework will take care of this always, right, you will never be in charge of this unless you're wild enough like us to just do it yourselves.

[00:05:32]
More what is interesting is that when you go to render a component and it sees that it's a server component. Normally it would just look into the bundle, find the code for it, run the React code and then render out the component for you. In our case, it's just gonna call the server and the server's gonna say, here's your mark-up.

[00:05:52]
So that's the relationship that's strongly changing here is, what happens when I render a component after the initial page load. And I want you to focus on that cuz the initial page load is less interesting here.
>> Brian Holt: Yeah, I feel comfortable with that answer, go ahead.
>> Mark: Will it reduce the amount of JavaScript that is rand?

[00:06:18]
>> Brian Holt: Yes, so that is one of the benefits of RSCs, is that all of these server components don't exist in your client bundle anymore, all of those components only live on the server. It's basically just like a stub to say, if this component gets rendered, call the server for what this is going to be.

[00:06:40]
As opposed to right now, when you have a client side component, all of the code that renders that comes with the bundle. So your bundle, in theory, can shrink a lot, cuz most of these components will actually live on the server.
>> Brian Holt: That is actually probably the biggest difference here that we're concerned with.

[00:07:02]
>> Brian Holt: Good questions, other questions?
>> Brian Holt: It's confusing, to be super honest with you, this is confusing stuff. And it took me a while reading blog posts, going through it, writing examples apps, reading their sample apps for me to finally just have that light bulb moment. It's like, none of this has to do with anything, right, it's an entirely new concept here.

[00:07:33]
>> Brian Holt: Okay.
>> Brian Holt: It definitely blends or it blurs the line a little bit of what happens on the server and what happens on the client, right? Because you're gonna be weaving in and out of, this happens on the client, this one happens on the server and it's gonna be fairly seamless for you for the most part.

[00:07:54]
>> Brian Holt: What you're gonna find here is Next.js one in with the controversial opinion. I think I'm okay to say that it's a controversial opinion, that everything is a RSC by default, and that you have to opt into the client side components. So it just assumes every components you're going to write from here on Next.js is a server component.

[00:08:12]
And that when you need client side interactivity, that you're gonna say this is a client component. Some people like that opinion, I can certainly see the valid take of why they would do it that way because many components are this way. It might even be most components are this way, they probably have data to tell you one way or the other, I don't.

[00:08:34]
The reason why people find it controversial, myself included, is that it's just a paradigm departure of how we write React code. For example, you cannot use useState in a server component, that's client-side state and a server component can't track client-side state, so it's hard, right? What you're gonna find about this, is like this does just change that you have to write React and it adds this additional thread in your brain of am I on the client, or am I on the server.

[00:09:06]
When you didn't have to have that before and that sucks a bit, right? It's additional cognitive load that you have to carry when you're writing a React app, and that's hard. Yeah, question.
>> Mark: Would RSCs be better or worse when it comes to slow connections?
>> Brian Holt: Everyone's favorite answer, it depends, [LAUGH].

[00:09:30]
It depends, there's no slam dunk here, because on a slow connection, if you download the entire React app, the entire app is now on your phone, right? And then you can just go through everything feels nice and zippy because everything is just running locally on your phone. When you have a React server component, every time you change the components, it's gonna make a server request, right?

[00:09:55]
So latency, not only becomes an initial problem, it becomes an ongoing problem, right? But if you have these monster RSCs that have lots of data in them and those renders are really hard on the device for some reason. Let's say rendering a million line table, right, one, why?

[00:10:19]
But two, that happening on the server is gonna be much better than probably happening on an old Android device, where the CPU just can't handle it, so it depends. Your time to first meaningful paint is also gonna be quite improved, and as you can see we're spidering out into these all these kind of edge cases.

[00:10:45]
But let's say you have an app that has 40 pages, and every user, on average, uses two. In theory, they're only get the two components that they need to render those things and they're leaving out the other 38. Likely that's a better experience for them depending on how heavy those pages are.

[00:11:12]
>> Brian Holt: On average they use 37 of those page on every visit, it could suck, right? So it could go either way as well. So, I'm sorry for not clean answer, but it's not a clean answer, right? Honestly, what we've gotten into is like, is it better to have a PHP server side pre rendered app, or is it better to have a React app, that single page application?

[00:11:34]
That is the exact same discussion that we're having right now. In fact, many people have pointed out that RSCs feel a lot like PHP, and I would wholeheartedly endorse that notion from actually a generally positive perspective. It's like I have a pretty favorable perspective of PHP from that perspective.

[00:11:52]
This leans much more into that kind of same paradigm, and it's the same argument that we're having. Okay, was that a sufficiently complicated answer to that somewhat simple question? [LAUGH] Okay, hopefully at the end of this, what I really want you to have is, its complicated relationship with RSCs, cuz that's kind of the relationship that I have, and I'm projecting as I do.

[00:12:22]
Okay,
>> Brian Holt: The coolest part about this is it makes a lot of this things were you had to make an API route and a client-side app route together to accomplish one task. A good example of I have a form that takes in 15 things from the user and then it saves it to the database.

[00:12:52]
How would you do that right now with a client-side React app? Well, okay, I get my form component, and then on submit, I submit to an API endpoint. The endpoint validates everything, saves to the database, responds back, hey, everything's okay. With RSCs, this becomes just incredibly simple we'll do server actions here in just a second, and it's all one step, right?

[00:13:15]
I have to write an API endpoint, your React app basically takes care of generating micro API endpoints for you because it's all one context to it. So that kind of code gets just wildly simplified by RSCs, it's actually very, very cool, I really do enjoy that part of it.

[00:13:38]
You'll see a strong upside and a strong downside here, if I'm doing a good job, hopefully you will see both. And that allows you to use things like secrets, right, so if you have OpenAI, if I have secrets to make requests to their service or something like that.

[00:13:55]
I can do that directly from my components now as opposed to on my Fastify API endpoint. So that kind of melding of concerns is nice, it works out really well. Yeah, it makes it very fluent to write these kind of client to server workflows, yeah, that's a good way of putting it.

[00:14:15]
Don't write RSCs by hand, it's all over their docs, please don't do this yourself, please rely on a framework that does this for you, because it's a really unstable API. But I don't like that, I like figuring out what everything is happening underneath the hood, and I think it makes me more grateful for the abstraction, and it makes me use the abstraction better.

[00:14:34]
So we're going to write everything down to we're gonna write flight protocol by hand. RSCs are meant to be implemented by frameworks. React like to maintain that it itself is a library, it is not a framework, I think that is a meaningless distinction that it is both neither and who cares, right?

[00:14:56]
But RSCs really are meant to be implemented by Next.js, by TanStack, by Remix/React Router v7/ whatever they decide to call it next week. It's a really deep integration into whatever you're shipping. So right now it's node only, I think that tracks because it has to render your React app, but there's some talk that they could.

[00:15:16]
It's technically possible to integrate this into, like a Rust app or something like that, no one is doing it right now, but it could be done. So right now, your options are basically just Next.js, it's the only one that fully implements everything. They make sense because about half the React core team works at Vercel at this point, they ship Next.js.

[00:15:35]
So, the React Router team has expressed that they are going to ship part of it, but not all of it. And then I actually spoke to last week, and he said at some point they'll start doing some of it in TanStack Start.
>> Brian Holt: I don't know enough to say what the Remix plan is for it, but the Next plan is just what I told you, that everything is an RSC by default.

[00:16:02]
And TanStack Start is the opposite everything is a client side by default, and you opt into server components. So both valid for different reasons, you'll have to decide which one you like better.
>> Speaker 3: What's the point of React Router, v7 doing it if they already have server client split for some actions, what's the advantage of having RSCs versus what they do today or they're splitting code?

[00:16:26]
>> Brian Holt: I won't speculate too much cuz I don't really know, the only thing I'll say about specifically the advantage of opting into the whole RSC thing is that it allows you to access. Be internals of React and ship this really compact, almost binary like format that then gets interpreted directly by React.

[00:16:48]
But you'd have to look further cuz I don't know after that, I haven't written Remix in a long time, so that's why. So, RSCs work today and Next.js don't work at all in either one of these to my knowledge. I think there's an unstable branch of both of these that have some RSC work in them, but you'd have to go look, so today, your option is Next.js.

[00:17:14]
And both of these frameworks have said that they're not gonna support all of it, that they only support part of it. So we're gonna write first our NotePasser app, which is going to be just pure Node, it's gonna have Node Next.js, so that you can see what it does.

[00:17:35]
And then we're gonna start writing some Next.js, and you're gonna be very grateful once we're into [INAUDIBLE] everything that it does for you.
>> Brian Holt: So the app we're gonna build is NotePasser, remember in school when you used to have to like rely on penmanship and stealthiness to get your notes to your classmates.

[00:17:53]
If you don't, you're probably Gen Alpha or something like that, and bless you. Back in my day, we couldn't text because there was no such thing as texting, right? That's not totally true, there was texting my time was in high school, but we're gonna build an app that kind of approximate that experience, it'll be fun.

[00:18:11]
Yeah, one note I just wanna throw out here, I had originally built this with a full on auth provider, and I realized afterwards, I was like why am I doing this? This teaches you nothing about React. So I'm gonna leave it as an exercise to you afterwards is like, go build auth on top of this, it could be a fun kind of way to learn more about some of these things.

[00:18:28]
But we are just going to assume that the user is always user ID 1 and that they're always correctly logged in. That's why I didn't add it here, is because it was a huge distraction to get pretty protected routes and stuff like that. Yeah, and then I get left to some ideas here Neon Auth, this is the one that I worked on at Neon, but like Clerk, Descope, there's a bunch of other cool auth providers out there that you can definitely try as well.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now