Matt Pocock is not here, so we're good. So, this is now officially a server component, conceptually. The problem is what? React cannot render promises. And anything async returns a promise. So we need some process to await everything, fetch all the data, and turn async functions into regular function components. We need that piece to exist.
How does that work? Let's look at it by checking out the next portion. So we'll get stash everything, and we'll check out number 2. So, some things have changed. This is now a full server component, async await. Let's go look at what happened on the server side. If we go to server.tsx, a couple of things. We have this new function now called unwrapjsx. Unwrapjsx, and this again is for the purposes of learning, it's way more complicated, but this is from Dan's thing. Unwrapjsx is a function that looks at your big React tree of objects, right? Every React application, once again, comes to type is, let's say type is a div, and props is something with children, and children could be literally like a deeply nested React set of objects, right? So this is valid. Let's actually maybe give it some value. Okay, so it looks at this. So this function unwrapjsx will look at this and go, children can be a string or a number or a Boolean or an array of things. This is actually legal. It could even be an async function component. It could be anything. Moreover, instead of a built in component that's a string, this is valid. And with server components, even this is valid, right? So a whole bunch of things are valid. So this unwrap function is going to look at all of these cases and return a weighted JSX. Clear? So if our JSX here that we're passing to it is a string or a number or a Boolean, which is valid, right? We could just do something like, like children could be this. It technically could even be this. In this case, we just return it as it is. If it's an array, we await all of any promises that exist in the array fragment. If it's an object, and then if that object is a react element, this property, $$typeoff, indicates that an object is not just an object, but it's a react element. So if it's a react element, then what? There's two kinds, right? There's functions and built in. So we handle the built in case by, if there's any async props, which may be children, we await them. For function components, similar. We await the props, we then call the function with its props. This is react, right? You call your component with its props, we await it, and then we unwrap that. So we just go through this whole long tree and await everything. And at the end of it, what do we have? We have a big tree with all the data dependencies resolved. Is that clear? We just have a tree with everything fetched. Then what do we do? Then, we hand that tree over to renderToString, or renderToPyblestream, or something that will then take the output of server components and pass it along the network. In this case, the server-side renderer, renderToString, renderToPylblestream, etc, becomes a client of the server component renderer. So the server is the client. It gets a little bit complicated, but that's essentially what's happening.
So what does this look like in practice? Well, if we come here to our router slash page, we're dynamically importing the default export. Before we renderToString, we've added another step. We unwrap the JSX. Unwrap just means await all the promises. So we pass in our application. We say, hey, if there's something async here, await all of that. And then give me a JSX tree with all the data dependencies resolved, render that to a string and send it. Let's see how that works. So keep in mind, we're not using React on the client side at all here.
Comments