Introduction to Next.js 13+, v3

Client Components

Scott Moss

Scott Moss

Superfilter AI
Introduction to Next.js 13+, v3

Check out a free preview of the full Introduction to Next.js 13+, v3 course

The "Client Components" Lesson is part of the full, Introduction to Next.js 13+, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Scott discusses the procedure for fetching data in client components and explains the limitations on passing serializable props between server and client components. By default, components in Next.js are considered server components, and to designate them as client components, the "use client" syntax must be included.


Transcript from the "Client Components" Lesson

>> Client components. So client components are the same things that you already know. You just have to opt into them. So let's make a client component. In fact, let's just go into our components folder. We're gonna make a few components here. We're gonna make a to do component.

We're going to make a to do list component. Like that. And there's one more. I'm just gonna go cheat and see which one. So I'm actually doing the same thing that's on here. Yeah, new to do form. So then I need to do form. So new to do form is a form where people can type in and make a new to do.

So there's some interactivity there. To-do just shows a to-do, it does have an ability to be clicked on and have the to-do be completed. And the to-do list just shows to-dos. So out of all of those, any one of those that probably has some interactions is probably a good candidate for a client component.

Because if there's interactivity, there's probably JavaScript. And if there's JavaScript, you can't run a server component, cuz you need JavaScript on the front end to handle the interactivity. You just do the same thing you normally do, right? Return a div with a form, and something like that. You have your input, something like that.

And then you did things you always do for a form. You might have some state and you got some update state thing here, that's a used state. And maybe it's just that. So, you could do that. There's nothing wrong with that. It's the same thing you've always done in React.

The only difference is now, actually I'm just gonna show you. I'm not even going to, I'll let next.js show us. I'm gonna take this component, I'm gonna try to import it into the page right here. Let's see what happens. I'm not even gonna try to use it, I'm just gonna import it.

I'm just gonna say new to do form. I'm just gonna do that. One thing you notice that it imported with this at sign. That's an alias that we have set up in our tsconfig. Add just means route. That way we never have to do @.we can just say from the route.

Do this. You can set up as many aliases you want, but here it is. So at anything, start from the root and match. So that's what that's saying. So that's just a shortcut. So I'm gonna import that. And then I'm going to try to run this don't get a problem yet.

So now I'm going to try to go down here. And we're gonna say new to do form, like so. Let's see if we get any. There we go. We got a problem. It immediately says you're importing a component that needs used state. It only works in a client component but none of its parents are marked with used client.

So they're server components by default. So it's basically saying like, you wanna do some JavaScript on the front end? You need to tell us that. So the only way to do that is to go to the top and say use client. I like that, that's it. So now that we have that, we're good to go now.

So putting use client at the top of a component, and then that basically obviously went to the regular React components that you've been used to. You can do user fact you can do use state you can do anything that you've normally ever done, and is gonna work exactly the way you think it's gonna work.

That doesn't mean this component won't be server side rendered. It probably still will be server side rendered like I don't know if I throw like, let's see what happens if I do this. As I say log, log of storage You can see right now I get an error, right?

Even though it's a client component, it's still rendered on the server, and that's because there's a difference between server side rendering and a React server component. By default, next.js is gonna try to render everything on the server, even this. So that doesn't mean I can go in here and just start doing browser stuff.

I would still have to check to make sure that if I'm in the browser or not, but this is a client component. So remember, service side rendering is this component is gonna be rendered on the server, but then there's gonna be some JavaScript that gets downloaded. That is the exact replica of this component that then takes over.

But we couldn't get to that point yet because I logged a window up here, which broke on the server cuz there's no window on the server. That's server-side rendering. A server component is like the same thing, except for there is no JavaScript on the front end that takes over it.

And the entire component is executed on the server so I can do database things. I could come in here and like log process or use Redis or a sync. I couldn't do that here. This would not work cuz it's not executed on the server. It's just rendered on the server.

So that's how you would do that. You would just use client. And that also means you can use client components in server components. And vice versa, the only thing that you can't do is pass props between them, right? Or, I'm sorry, you can't pass non-serializable props between them.

So what does that mean? Let's say I have some props here that says like, on change, right? It says on change prop, which means it's probably a function, okay? Then I go to page and I like cool. Yeah on change, like it's passing. Let's pass in a function here.

Like that, hello. Okay, and then we try to refresh this it's got a break. Event handlers cannot be passed to client component props. If you need interactivity, consider converting part of this to a client component. And, it literally tells you. So, what does that actually mean? It's saying, the reason it says that is because you cannot serialize a function.

If you don't know what I mean by serialize a function, this is what I mean. So, if I go into the console, and I do something like this, let's say I say json stringify this object, right and this object has a name called Moose. And then it has an action and this action is a function that does something, okay?

By stringify this what do you think the JSON is gonna look like?
>> Going to blow up, right?
>> I mean, I guess it doesn't like that. Let me let me be specific, since it doesn't like when I do that. Okay, yeah, it's totally gonna blow up. Well, hold on, I guess I'm missing a bracket here.

There we go, okay. So what it actually did was it didn't carry this over, this function, right? Cuz you can't serialize logic, at least not this way, not with stringify. There are ways you can do it, and some people do it, but by default it's not gonna get carried over.

And because you have a client component and a server component, that communication has to go across the network barrier. So it has to go through the network. And to go through the network, you need to be serialized. Cuz you can't just send code through the network. It has to be something that is understood.

Data, in this case JSON. But when you try to stringify a function, yeah, it's not gonna be there. So this is why you can't pass functions as props cuz they can't be serialized. There are other values that can't be serialized as well. Dates, you can't serialize a date, you can't serialize recursive things, things that are like cyclic in nature.

So an object that points to itself somewhere, can't serialize that. So things like that you have restrictions around that. So, those are the only caveats.

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