Current section: Server Components 27 exercises
lesson

Intro to Server Components

Loading lesson

Transcript

00:00 Okay, let's talk about bringing server components into our single page application. Before we get into that, I want to compare the typical single page app with the super simple React server components and actions example. This is super simple because it's no dependencies and no optimizations and stuff.

00:19 So let's look at the SPA example first. A user goes to a website that's going to hit their browser. They're talking to their browser. The browser will go and talk to the server to request a document. The server will send the document back. So this is our index.html. And it's going to render a loading spinner. We've got that right now in our application.

00:36 So if we refresh this, there's our loading spinner right there. So the browser shows that to the user. And while that's happening, it requests some client-side code. That's our, you know, go get the slash UI and all that stuff. And in fact, actually, we show the loading spinner after the client-side code shows up.

00:54 So we could put something, some loading state in our index.html, and that would be like rendering the loading state. So in any case, we request client-side code, we get it back, and we show that spinner. And that's how we display the updated UI components is that loading state.

01:12 And while that is happening, we go and request some data. The server will generate that data response, send the JSON response, and then we take the data that we got back and the React components that we have in the front end. We stick them together. That turns into React elements. We pass that on to React DOM. That turns into DOM nodes.

01:29 And then that gets the updated UI to the user. That's pretty typical of single-page apps. Every architecture is going to be a little bit different. But this is kind of a general overview of how single-page apps works. So if we're going over to RSCs, it actually doesn't change a whole lot. So we're still going to the site, requesting document, document comes back.

01:48 And then the front end is going to request a JSX payload. So rather than requesting the... Well, actually, you know what? We do kind of request client-side code, and we also could render a spinner in our index.html. So we're going to request client-side code, but for minimal things.

02:08 And that's why there's this distinction. So it's just for that index.js file. We're not going to be needing to request the app.js or any of those other things that we request for our typical SPA. So that UI index file is going to go and request a JSX payload.

02:26 And we're going to render that suspense fallback that we had with just the question mark ship thing. And this is going to generate serialized JSX with react-server-dom-esm-server using rendered a pipeable stream, which we'll be using in this exercise. So that will stream serialized JSX.

02:45 So we'll talk a little bit more about this later, but this is a critical point is that it actually can send pieces over time, which is pretty cool. So this will render the streamed UI with react-server-dom-esm-client using create from fetch, which we'll be using in this exercise.

03:03 And then there will be pieces of this, of your UI that are interactive, and that will all be configured or present in the serialized JSX that gets sent to the browser.

03:17 And so the browser will see, oh, we've got a couple of these things and these different modules that need to be loaded. And so it will load those modules, respond with those modules, and then it will hydrate or make those client components interactive.

03:34 So they're actually like if you squint, these look like very, very similar graphs. There's not a ton that is different about these. And really, if you think about it this way, we create UI by having a react component and

03:50 data, stick them together and poof, now we have our UI. And that, in a spot scenario, is going to happen on the client in the browser. What we're doing here with server components is we're taking that and moving it over to the server. And so instead of sending the data over, we're sending the UI over, and that UI is going

04:09 to be serialized so it can go across the network, and then deserialized so it can be turned into React elements again, which can then be rendered. And it's a bit more of a complex process. Some of you are thinking like, why don't you just generate HTML on the server and send the HTML? Then that works nicely, right?

04:28 Or maybe you're thinking that's exactly what it is, but it's not. It's a special format just for React server components because of the capabilities that they get by having their special format, which we'll look at in a future exercise. So at this point, we're just trying to switch from the typical spa scenario of requesting

04:45 JSON data into the React server component scenario where we're requesting RSCs, that RSC payload. Speaking of the RSC payload, this is what that looks like. It's kind of like JSON if you squint.

04:59 Each line here is a bit more of JSON, and they're separated by lines because they're actually streamed in. So, like, you might get this much, and then you'll get some more, and then you get the rest of it, right? So over time, they can send more and more and more of this stuff.

05:18 So it's pretty cool. There are references all over the place, and I'm not going to dive too deep into this specific format. It's kind of an implementation detail. But it is useful for you to understand that what gets sent over to the browser is not quite like React elements.

05:38 It's like a serialized version of that. And there are references to client components and things, all of which we're going to get into. If you want to dive into this a little bit more, then there's this RSC parser utility that you can use to kind of explore things.

05:53 So there's a default right here, but we can also copy our own and stick that right in here. And then you can explore a little bit and be like, oh, that's my fallback loading state for all my ships or whatever.

06:07 So at this stage of our workshop, we're not here with our RSC payload. There are a bunch of features that we're going to be adding later that will add fallbacks and different things like that. But yeah, this should give you kind of an idea of what to expect from the payload that

06:27 we should be getting from our server when we make that request for RSCs. Speaking of, how do we generate this RSC payload? So here on the server side, we're going to be rendering React. So we're going to bring in H or create element as H, that stands for hyperscript, from React.

06:46 And then we have rendered a pipeable stream. This is coming from React server DOM ESM. Now this package actually does not exist. It's not, well, technically exists, but it's just like a placeholder. Because it is a really, really simple implementation of the RSC specification, and it is missing

07:05 a lot of optimizations and things, the React team doesn't actually want people to be using this in production, but it works out great for us. And so what we're doing right now, this is implementation detail of the framework or of the workshop, and this could actually change in the future. I'll update all the material if it does.

07:24 You don't need to worry about this changing. But right now, I just have React server DOM ESM coming from npm colon at kensy.temp React server DOM ESM. So even though this isn't technically published on npm, I'm able to kind of simulate that

07:39 using this special feature of the package JSON versions, which I think is actually kind of cool, but I wanted to show it to you so that you understand how this, how I'm managing to have us running React server DOM ESM, even though that package is not technically published to npm.

07:56 I published it myself after building this package from the React repository manually. So that is useful information for you to know. Okay, so we have rendered a pipeable stream. This might be familiar to some of you who have actually built server rendered applications

08:12 with React before, because this is a common API for other React packages for server rendering. This one is different, though. Those other packages will send HTML, convert React elements and turn them into HTML.

08:26 But this one takes React elements and turns it into this special payload, which can be streamed over the wire. And so here's how we are doing that with HanoJS. So we create our components. We can pass props or whatever. We pass it to rendered pipeable stream.

08:44 And then on the UI side, we have a React server DOM ESM client. So this is in the browser. We are going to need to update our import map for that, right? So we update our import map, and now we can import this, and we get this create from fetch. So we make a fetch request to our RSC endpoint.

09:02 That promise goes into our create from fetch, and create from fetch will resolve that to UI, which we can then pass into render on our route. And that UI is really just going to be React elements. You could console log it. It'll look very familiar to the create element API that you're used to.

09:20 But it came from the server. So that is what we're going to be doing in this exercise. It's going to be a good time. There's plenty of stuff for you to do to explore once we get server components actually implemented. There are just things that kind of fall out of this particular format.

09:37 This capability of rendering the UI as it comes in, we'll have like async components and streaming, and we'll talk about how to deal with server context and avoid prop drilling problems and stuff like that. So it's going to be great. I think you're going to have a good time with this. The format is kind of funny.

09:56 I hope that you actually will hit the RSC endpoint so that you can see what that looks like. You can go to one of these pages and then add a slash RSC on there to see what that looks like. Right now, before we change this from API, you could go to slash API, and that will show you what the API looks like.

10:16 But if you do this when you implement the RSC endpoint, then it will look kind of cool. You'll see something that looks a little bit like this. But especially once you do the streaming stuff, you hit refresh and you'll see it like here comes in a little bit, and then here's a little more. I should stop talking because we're actually going to get into this. So let's do that now.