Introduction to Next.js 13+, v2

Introduction to Next.js 13+, v2 Data Fetching with Server Components

This course has been updated! We now recommend you take the Introduction to Next.js 13+, v3 course.

Check out a free preview of the full Introduction to Next.js 13+, v2 course:
The "Data Fetching with Server Components" Lesson is part of the full, Introduction to Next.js 13+, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Scott discusses fetching data in server components to keep apps secure and reduce the load on the main thread. A demonstration of fetching data from an API is also provided in this segment.

Get Unlimited Access Now

Transcript from the "Data Fetching with Server Components" Lesson

[00:00:00]
>> Now we're gonna talk about data fetching. So this is probably I think where Next.js 13 shines other than server client components is definitely this. This sweet sauce is where I'm like, okay, I don't know if I was filling in at first, but after using this, I was like, I can't go back.

[00:00:16] This is actually the best way to develop application in my opinion. It was just when it comes to this. So let's talk about these pages, layouts they might need data before they render like, for instance, look at this example, home page here. All this is static content right now, but what if all this content came from a CMS, right?

[00:00:38] Everybody uses headless CMSs now, that's an API call. How does that work? How would you get this content here on this page and have it be SEO friendly? Don't give me, well, Google crawls JavaScript, don't give me that. How would you make it SEO friendly if I was to post this on Twitter, right?

[00:00:57] Twitter doesn't crawl JavaScript, so you would have to render this on the server, right? So you have to do server side rendering next year support server side rendering, so cool you solve that problem. But then the serialized data got shipped to the client. And that's just bloating your client-sized JavaScript bundle, which slows you down, it's just not good.

[00:01:18] And then you need Astro, and then you need all this other stuff. So one way is like, well, what if we only fetched it on the server? Because this stuff is just like read only, and maybe something else is dynamic over here and it's like how do you isolate that, right?

[00:01:33] This is where server components come in as like I can isolate different parts of the app that have special needs depending on their data fetching. So basically, inside of a server component, you can fetch data with so many different ways. You can use something that looks like window.fetch, and we'll talk about it.

[00:01:55] So if you ever use window.fetch next, well, I think Reactor actually did this, reacts did something with fetch, made it global and allow you to customize it in such a way. And it has like superpowers and I'll talk about the superpowers, but you can also interact with the databases direct you gotta ORM that you use.

[00:02:12] You like using Prisma, something like that. You can just use that directly in your component. You don't have to make an API call that they didn't talk to Prisma. Invalidates the user with authentication nope, you can just talk to the database right in the component right next to the JSX like right there.

[00:02:27] Which I think is insane if you think about it and the same thing with like third party SDKs, maybe you're using Stripe. Maybe you're using some other SDK, you wanna interact with it. You can do that right in the component. You don't have to go through an API and do that stuff.

[00:02:43] You can do it right in the component. So you could do that with server components, which I think is, like, super really cool. And obviously the benefits of that is that you don't have that network layer which has latency and overhead and all the stuff. You keep your app more secure by not exposing potential API keys to the client, which is always a problem.

[00:03:01] And you have to rely on the API provider to come up with a private key, or a public key, type of situation, which is always kind of weird. Especially if, you're being charged per request for CMS and someone gets hold of your API key on the front end, and they're just, spamming your site and now, you're paying your CMS a lot of money.

[00:03:17] If for some reason because you didn't build your site, right, it's happened before. Reducing the load on the main thread in a browser because there's less JavaScript. There's no communication between a client and a network. And that network, like getting data, so that T stat connections not even open.

[00:03:34] It's just it's not even there, he's never crossed a network threshold. By time the browser saw the constant, it already happened on the server. So it's reduced overhead. So now the main thread can focus on things like animation and putting things on the page and just a lot smoother.

[00:03:47] So yeah, and then many more reasons. There's tons of reasons, but those are like some of the big ones, but let's talk about fetch. So fetch, React extends the fetch function to provide automatic requests de-duplication. This is on a per request basis, so let's talk about this for a second.

[00:04:05] So I'm gonna go into this page here and we can take some of this data out and like put it somewhere or we'll just hit an API, we'll make it easier and we'll hit an API. So API that I always like to hit is Reddit. So if we go to reddit.com/.JSON, right?

[00:04:25] If you go there, you get Reddit as JSON. I don't know if anybody knew that, but you can just do that without API keys, petty cool. So I'm gonna grab the zero, and I want to access that data in this home component because maybe I wanna put this stuff on my home page, right?

[00:04:42] So before server components, I would have to make a route in our APIs, which we'll talk about, eventually. And then that route will make a call to Reddit, and then it'll return the data. And then I'll get the data back from API and I can put it on the page, that's one approach.

[00:04:59] The second approach is I would just call Reddit from the client after it boots up and use, like, a hook. And then, when it in the user effects, I'll put it in there and then it'll get Reddit, and then I'll load it in and I'll set the loading state and do all this weird stuff.

[00:05:11] Those are the two ways you can do it, both of which are costly as far as the runtime. But the server component, I can just do it directly in here. So what I'll do is I'll go to the server component. And the convention that I see people starting to do is they'll make a function called like get data in their server component and then get data is just gonna be like some async thing.

[00:05:32] And then in our case, I'm just gonna say data equals await and I can just call fetch like this, I can pass it this URL. And it works very much like window.fetch. In fact, it is exactly like widow.fetch, just enhanced, so we can fetch. And we can do things like configuring the cache, but we'll talk about that stuff in a little bit.

[00:05:52] So we got the data, and I'm just gonna return data.JSON, right? So now we got the data and then check it, I can do this or if I can spell it right. I can make this component async this is something you cannot do on a React client component.

[00:06:13] In fact, you've never been able to do this in React ever, right? This won't work, if I change this to a client components will break because React components aren't functions there are components with life cycles that run over and over and over again. This is why you have to have a hook because if you don't when the component re-renders any variable that you are trying to keep track of, resets.

[00:06:34] Because the function runs again, so you need a hook to tell React hey, don't lose track of this variable for me across re-renders. Well, this thing doesn't have re-renders. It just happens once on the server, and then it gets cached, depending on your re-validation strategy. So I can async this, and then now I can say, hey, you know what?

[00:06:52] Block, don't render any of this JSX yet until I get the Reddit data. So I can do that now. So this will block the rendering of the page until this comes back. And then I can get the date and I can do whatever I want here. Let's look at the data though.

[00:07:09] So I can actually do something with it. So we got data.data.children.data. So let's get like one of the first ones. So we'll say a post is data.data.children

[0].data. And then there is a title on here. There's gotta be a title on here somewhere. Name, nope, there it is. Title, I knew it, okay, cool.

[00:07:41] So we got the post and then I can just go ahead and just say, let's put that here. Post, here we go. If it all works, we should see a title here, if it all works. So let's see what happens. Let's go back here. It's already there, I didn't even refresh, sorry there.

[00:07:59] So because it happened on the server, right? This didn't happen on the client's side. This page doesn't even show up until it renders. In fact, if you look just a little zoom in if I do this? Let me see, yeah. If you just look right here, when I refresh it, it actually does take a little longer, see that?

[00:08:20] That was it fetching the Reddit data, right? If I didn't have that, it wouldn't take that long, it would have happened immediately, right? And I can really exaggerate this by like putting a set timeout here for ten seconds just so like we can actually see it, but the guy get the point.

[00:08:34] It's not going to render anything here until it gets the data, which to me makes way more sense than the way we do it now, a client opponents was like hooks. And trying to figure out the order of which things are rendering is like, why can't I just wait till I get some data back before I render this stuff?

[00:08:50] Versus doing, like, a if statement and, like, if the data is not there, then do this and this use effect, right? To me, mentally, it makes more sense. It works the way you think any function would ever work. It won't move forward unless this is done, just like any function ever works.

[00:09:05] So that's because it's server side and it's opting out of the React reconciliation phases and things like that. Whereas client side is business as usual. It's not gonna work this way on the client side. And this is why it's very important to know if you're in a client component or not, right as soon as I add this.

[00:09:26] You can forget about it right or done, it's not gonna work. I mean, I don't even know what error is gonna throw at this point, yeah, right here. Promise you can't put a promise right there, render a collection of children, you can't do that because we're in the client side and you can't do that, so big difference there.

[00:09:45] And you're not limited in scope of what you do here. So we talked about fetch and how it works and I talked about being able to extend it. The caching, we'll talk about that a little deeper because that. That's just course by itself is like caching with fetch, but you're not limited to just only doing fetch.

[00:10:06] You can do whatever you want inside of a sync opponents, so for instance if you're getting something without fetch like a database call or an SDK. You could put that in there was nothing stopping you if you had stripe, you can use stripe in here if you had Prisma.

[00:10:22] And you were doing some Prisma stuff in here you could do that in here, there's literally nothing stopping anything you do on the server side you can do in here. Because it has access to the server, so it's very powerful. It's just that React index has hijacked the fetch method and expanded it to have like control around caching, because they use the caching to determine whether or not they should re-render a component.

[00:10:45] If something is being revalidated, that's going to trigger a render. And it gives you the tools to be able to play around with that caching, but it's really advanced, it's really only for production. For the most part, you should just opt into the default caching mechanism that React does, which is pretty good in most cases, which means don't do anything, it'll just work.