Sharing State Between Server and Client Components using props

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the Next.js Complex State Management Patterns with RSC course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to Next.js Complex State Management Patterns with RSC, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Next.js Complex State Management Patterns with RSC
  • [00:00 - 02:29] Welcome to lesson 2 on this module about sharing state between server and client components. In this video we will uncover the practicalities of sharing state between server components and client components. This very basic technique allows state to flow through our application in a structure and predictive way. So let's go. Let's first answer the basic question, why do we need this? Remember that when we're talking about server components, we're talking about components that don't have or at least don't handle the same concept of state that we do when we talk about it in the context of a client component. So that means that if we have a piece of state or data that is generated on the server side, we need to find a way to share it with our client components essentially with everyone. But in particular with our client components because that is where our users will interact essentially with our application. And this is no problem where we're talking about client components simply because when you're in browser land essentially we have ways to share state between components. We've seen them already, context API and so on. So this is definitely not a question that you ask yourself. You know, how do I share this state? There are tools, there are libraries already at your disposal. But how do you do it if the data originates, if the state originates on the server side? Let's answer that question. Let's quickly recap. With props, we can pass data from a parent component into a child component essentially. And if you do prop drilling, which is something that we discussed in past videos, you keep passing that data through from parent to child component until it reaches the right one that you want. We 're not doing prop drilling here, but we're doing just the first step essentially from parent component into child component. In this case, where the parent component is a serving component and the child component is a client component. And in the context of next 13 essentially, that is very relevant because as you remember, there is this thing called server component payload that takes the output of your server component rendering process into the client. And with that output, you also have the props that you pass into any client component. And so as part of that payload, we're going to also have props. So I'm showing you here some code that you've seen already in many times because I've used this example in several cases, the net back component.

    [02:30 - 02:43] This is the final form of that component, as I already showed you before, in the previous module. In this form, this is a server component that is pulling data from the database when it's rendering in the server.

    [02:44 - 04:41] And then it is storing that data in the user variable and sharing it as a prop to the user menu component essentially. So this is going to be a very common practice when you do data fetching on the backend and you want to share that information that state with your client components whenever it's relevant, obviously. But the point here is that there is data transfer here, essentially, there is no magic. We are transferring data from the server into a client implicitly. And that is the key here, because we are not, as you can see here on this piece of code, we 're not writing any dimes that will transfer that code. We're not even, you know, we're just at a high level, we are sharing data between components, but we're not really taking care of the process of sharing that data. How is that data shared? And that is where, again, next year's comes in and solves that problem for us through the server component payload. So what are the advantages of doing something like this? We have now successfully combined server and client components through props, which is great. We perform a base load with a responsive and interactive experience, essentially, because we are loading the data quickly and at the same time, we're sharing it efficiently through the client and the client is providing that interactivity to the user. Passing props is undeniably simple, as one of the main reasons why you want to do this. It doesn't involve complex state management, libraries, or anything, really, just using a very basic mechanic that we have already provided and has been providing for years. This is just an extension of that by combining two components that should not be interacting with each other, thanks to next and react serving components . We are able to reach that gap. And I think that's the main reason why you want to make the most out of this technique.

    [04:42 - 09:17] You don't really have to set anything up that's already set up for you. You don 't really have an external libraries. It's already provided for you. It's a mechanic that you 've used in the past for years. So, again, you don't really have to think about it differently. It definitely works differently behind a carton, but it doesn't really affect the way you code or affect the way you think about components. So, that's also something great to think about. However , because, you know, because, like I said, this is not magic. There is data transfer, there is a mechanic behind the carton that we're not seeing. There are limitations to this technique. If you 're used to passing props into components, you know that you're not limited in any way when you're dealing with components that live in the same context, essentially, for client components, which is the type of component that you're used to handling. You could pass data, yes, definitely, but you could also pass objects, complex data, objects with methods and internal state, you could pass even functions as part of the props. And that is where we draw the limit here with the communication between server and client components. You can only pass props that can be serialized. That is the only limitation, but it's definitely something that might affect the way you've reasoned about them if, you know, like before, you're used to also passing all the more complex data or more complex entities through the props. In the context of server and client communication, you should think about props as a way to share data, share state. Not think about them as the usual prop that you're used to think about in the past. Here, I'm showing you what that limitation translated into, essentially, the getUserByID function, which is this is a simplified version of the one that we have on the sample application. This function is pulling data from Mongo database, and then returning, essentially, the user is picking a user and then returning it. However, I'm just doing a parsing of the stringified version of the object, because if I just try to pass this object as a prop to my client upon it, it will not work. React and Next will not let me pass objects, even if they have a two-json method on them that could potentially implicitly perform transformation. I have to do it myself. There cannot be any non-basic data that let's put it that way inside the entity that I'm trying to share. In the case of my user, because this is a MongoDB document, what I would get is my ID being an object ID. If you talk with MongoDB in the past, you know that the underscore ID property of whatever you get from the database is actually an object. That is a minor issue that gets easily solved by doing what you see on the screen. Simply turn an inter- json explicitly and then parse it back. Then you get an actual JSON that is fully serializable. It's not really a big deal. You just have to have this inter-concuration whenever you're trying to pass complex objects from a serial component into a client company. That's really about the only kind of limitation that I would put into this technique. The only piece of warning that I would give you is that if you definitely need to share a state that gets originated on the server with multiple components on the client side, don't fall into a trap of doing prop drilling. Don't just think that just because you're passing the prop initially from one environment to the other, you have to keep passing it as a prop to the other components. Just go back to, if you want to look into that, go back to the previous video on module 5, where I showed you how I improved the data loading on the list of tasks. Remember that I was doing the data loading on the server component, sharing it with the client component through props, and then on the first list component, I was populating my context API essentially. I was using the context API to populate the internal state of my task provider, and through that context, I was churning through all the other client components. If that is something that you need, which is a very common case, by the way, I mean if you're generating a first-generation state on the back end, and you need to share it, it's usually with the entire application, not just with one single component. So when that happens, do it that way. Use props for the first component, and then once you have access to the context API through a client component, use that. That way you get the best of what work essentially.

    [09:18 - 10:25] So to wrap this video up, passing props remains a very valuable tool, even when you're on the back end and trying to share information with the front end. Server components make that very easy. It definitely enables you to effectively manage state transitions from server to client components in next application. So this is definitely a plus, something that next implemented and empowered through React 7 components. While it's not the only solution, and we have still two more videos to show you two different techniques, or always the best choice honestly, it's important to consider this pattern for simplicity and directness essentially. There's nothing easier than just passing a prop from one component to the other. So keep that in mind. Next time you have state that is originated on the back end, and you're wondering how to share it with your front end. So in the next video, I'm going to show you how to take advantage of cookies to use them as a state storage in a way that you can share a state between client and server components back and forth.

    [10:26 - 10:29] So in the meantime, keep coding, and I'll see you on the next one.