This course has been updated! We now recommend you take the Introduction to Next.js 13+, v3 course.
Transcript from the "Client Components" Lesson
[00:00:00]
>> We left off last discussing rendering with server components where we talked about difference between server components and SSR. When to use server components, where you might confine the RFC or the request for comments on the original proposal for server components on the React team, which I do recommend reading a lot of context there.
[00:00:22] They have some videos and conferences, conference talks that you should check out as well. So, highly recommend it only because I've looked at them myself and I've learned a lot. It's very enlightening. So, but what about client components? Well, we talked a lot about client components, and just to rephrase again.
[00:00:42] Client components are just the regular components that you've been using this whole time and React. And that's basically it. They are now officially called client components. That's the official name. And I think having that distinction actually makes it easier, because I remember when I was learning Next.js, or even before Next.js, I remember figuring out how to make service site rendering with React before there was even a Next.js.
[00:01:04] It was very confusing to think about where a component was gonna be rendered, and when it was gonna be rendered and how it was gonna be rendered? And there was this whole concept of universal JavaScript and it was like, I don't know when this component's gonna happen. Well, now there's a client component, and there's a server component.
[00:01:20] So it's a lot easier to think about as far as like the context in which these things are gonna run. There's still definitely some complications around it and frameworks like Next.js aim to solve those complications or make it less difficult, but at least there's a distinction around. This is a client component, this is a server component.
[00:01:35] So, I'm also very curious to see what other frameworks do now that React has done client component, server components. I think other frameworks might follow as well just like they did with hooks. So, we'll see, I think there's gonna be a big change in JavaScript ecosystem entirely. But yeah, client components.
[00:01:54] I have an example of how to use them. But in reality, like I said, they're literally the same thing you've always used. You just have to add use clients at the top. That's it, there's nothing else different about them. That's literally all you have to do. And it's the exact same stuff you've been doing.
[00:02:08] So in the case of Next.js, those client components can still be rendered on the server statically, dynamically, but they're not server components. They're just client components rendered on the server. They don't support a sync data fetching, they still can use client side API's inside of them like hooks and use effects and things like that, because they're eventually going to be hydrated on the client.
[00:02:32] And taken over so, they are still actually client components here's getting that initial HTML on the server which is not the same as server components that never leave the server, they always stay there, they can't have state, they can do async data fetching, they have access to code.
[00:02:49] They're actually being executed on the server, right? Versus just the HTML being rendered. So, when would you use client components? Basically, if your components need hooks, like useState and useEffect, then you need a client component. You literally cannot use a server component with those things. So, if I try to go into the server component here, let's go back here.
[00:03:16] So, notice in his homepage, we don't have use client anywhere, so by default this should be a server component. So, if I tried to say, useState, let's import useState here, and I say state, setState equals useState like this. I just saved that. Then I go back and right here, medially because I didn't even refresh, we already got there, right?
[00:03:48] And you can see right here, you're importing a component that needs useState. It only works in a client component. But none of its parents are marked with use client. So their server components by default. So you kind of get an error right here, from the React compiler, the tool that's running React.
[00:04:06] Yeah, you can't use this, because how would it work? There's no state on the server. It's not rendering. There's no reconciliation phase. There's no dirty checking, there's none of that client side optimization happening on the server so which is what the hook was created for. So, yeah. You also can't use class components for server components.
[00:04:26] So, if you are still using class components, those have to be client components, because they don't work on the server. I don't know if that's in the doc somewhere, but I just ran into that. I just happened to try it and I was like, yeah, these don't work.
[00:04:38] So yeah, you will get this error a lot. So, don't rely on the error though. Remember, if you need a hook, it's probably a client. If you need a DOM event, it's probably a client. Other than that, it's a server.
>> Based on this, I might be misreading the error message, but does this imply then that any child component, all of the component that has use client as that directive will kind of by default, the opposite into rendering on the client?
[00:05:08]
>> It's going to look for the nearest parent with the use client, right? So, if you can add a server component to a client component, as long as server component is wrapped in a client component [LAUGH]. Right, so, I can't bring a server component directly into a client component without it first being wrapped in one, right?
[00:05:31] So, we can run through some of these examples here, but let me get through this last bit I got and then we can run through how to interchange some of those differently. So you can see the different error message, because sometimes error messages are like, I don't know.
[00:05:42] But yeah, we'll see, okay. Good question, though, okay? So, when to use client versus server. So I already talked about when to use clients, when to use servers. Now, I'm going to compare the two, but it's mostly the same, but always use server components for all your components unless it falls into one or more of these.
[00:05:59] It needs interactivity or event listeners, like onClick, onChange. It uses state and lifecycle effects, useState( ), useReducer( ), useEffect( ). It uses browser-only APIs. It needs custom hooks that depend on state, effects, or browser-only APIs, and then React class components. Again, that's the only reason why you would ever use client components.
[00:06:22] I think the only other ones I could think of that's i guess if you were using something like Chakra, some third party library, and you really wanted to use it, and they just haven't updated it to work for server and client, then you have to use client components for that too.
[00:06:39] But that's just a lot more tedious. You actually have to, every one of those components you have to use, you have to wrap in your own client component that just returns that component. Just to put the use client at the top. So, I'm pretty sure someone's gonna make a tool that does that for people automatically, so they don't have to do it, because that just sounds annoying.
[00:06:56] So, they actually wanted to do that. So, if anybody wants to make something make that, it'll be very helpful. So, it's like use this babel plugin to wrap third party libraries with the use client, and it just works by default that actually really cool, okay. Let's run through some examples, okay.
[00:07:13] One thing you might not know is that we could just make a new folder on the and let's say we call it components. You can use server and client components in this folder too, not because it's called components, but because they're eventually going to be imported in the app directory, which supports server and client components.
[00:07:31] So your components don't have to live in the app directory. They just eventually have to be pulled in here eventually through another component or directly. And that's how they are able to have access to server and client components. Whereas, if they were imported in the pages directory, they would not be able to do server and client components, they would instead use Next.js 12, which does get service props and get static props, yes.
[00:08:01] So, that's the difference. So, highly recommend only using the pages directory for the API, not the pages, and use the app directory for all the pages. If you're using Next.js 13, reason 12, you will never even use the app directory. You will only use the pages directory. Okay, so let's see some examples.
[00:08:24] So for components, let's make a server component here. So, we'll make a component, that's like a header. All right, so we have a header here. Something like this, Whoops. I got a header here. And it's nothing special, it's just a header. Like that and some logo or something like that, right?
[00:08:52] So, I didn't put use client, so by default this is gonna be a server. I didn't put use client, right? So now, if I want to bring this into any other component in the app directory, let's say page, I can just import it, Like that. And then I can just add it here, wherever I want, just like any other component.
[00:09:18] It's no different, there we go. And I can go check it out. I still have you stayed in there. Yeah, I do, sorry. There we go. So there you go. There is our logo with our header, it's there. So, importing a server component into another server component, it just works.
[00:09:45] You don't have to do anything about it. Now, let's say I make the header a client component. So, i'm going to go to the header and I'm going to say, use client. All right, let's try that. Now, what happens if I refresh this? Nothing, it still works. What's actually happening in the background is that this component's actually being hydrated and filled in on the front end.
[00:10:07] You just can't see it because it's a small component that's not doing any data fetching. So it just happens instantly. And I'm a local host, but if this component was fetching data and I wasn't on local host, it would pop in much later than the rest of the page did.
[00:10:21] So, because it's a client component, okay? So, another example is what if we use a client component, or what if we use a server component in a client component, right? So, let's try that. So let's make another server component inside our components folder. And we'll call this HeaderLink, something like that.
[00:10:41] All right, so we say HeaderLink, It's gonna copy this. That HeaderLink, and it's just gonna be a div. Just header link. And then we'll make it a server component. So, I'll get rid of these clients like that. And then I'm going to import it into our client component which is the header, let's see what happens.
[00:11:13] So, your HeaderLink here. And I'm going to save it. So before I go, refresh, anyone want to guess what they think is going to happen if I try to do this?
>> It'll get rendered on the client because it's immediate parent is a client app. Unless I'm totally wrong.
[00:11:38]
>> That's logical. Yeah, that makes sense. Anyone else wanna try? I'm not saying you're wrong. Just wanna know if anyone had any other thoughts.
>> That's what I would've guessed as well.
>> Yeah, okay, let's see what happens. Yeah, it's exactly what happens. Yeah, it handles that for you, because it's immediate parent is a client.
[00:11:58] So it kinda just works out. And these examples are trivial. But once we get into like fetching data, and you see how we can load them in and parallel or after each other and things like that, it's gonna start making more sense because we're not fetching any data right now.
[00:12:13] This is all just like why we just make all this stuff servers just like read only data, but once we start fetching data, you'll see the intention behind this whole new concept of server versus client. Because that's what it comes down to is fetching data and how much JavaScript you're sitting to the front end.
[00:12:28] That's really what all this is about and then also just like taking advantage of Async React using suspense and stuff like that, which I think a lot of people just haven't taken advantage of because it's quite honestly, really hard to wrap your head around. So, Next.js also has a really good guide in their documentation on common pitfalls to look out for when you're trying to import a client component in the server component or vice versa.
[00:12:54] They're really weird use case ones to check out. So, check them out if you want to.