Getting data, statically

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 Blazing Fast Next.js with React Server Components 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 Blazing Fast Next.js with React Server Components, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Blazing Fast Next.js with React Server Components
  • [00:00 - 00:10] React Server Components can render HTML and other React components. They can render other React server components, but also other React client components.

    [00:11 - 00:29] The point is not just to render static HTML, we want to render dynamic content, like the products of our product list here. To achieve that, we need to get the product list from the database or any kind of API that can provide this information to our website.

    [00:30 - 00:43] So we are going to discover how it can be implemented. So here we have the product list, we have the product item component, displaying one item, it's just HTML taking the product definition as a prop.

    [00:44 - 00:54] So really like a template, but we want something smarter for the product list. So here we have the exported version, more on that later, it's a bit complicated.

    [00:55 - 01:03] Here we have the code that actually gets the data. So we see that it's an asynchronous React component, an asynchronous function.

    [01:04 - 01:11] This is not possible in client components. Only server components can be asynchronous this way at the moment.

    [01:12 - 01:33] Having asynchronous components like that that can then use the "await" construct is really something new in React. Now, given that the component is asynchronous, it can also use the await construct directly to await database calls, for example, a fetch call, anything that is asynchronous, a long running computation.

    [01:34 - 01:45] Remember that accessing a database or communicating with a distance server is always something that is asynchronous. In client-side React, I showed the code here that you would have needed.

    [01:46 - 01:53] You would have needed a useEffect. We have a fetch code and then some state that sets the product list.

    [01:54 - 02:06] But with a server components, you only need to actually get the data. And the part that gets the data is abstracted away in this function, "rscGetProducts".

    [02:07 - 02:23] Let's dig what it does. So if I jump to its definition, I can see here a function that sends an array of products and well, it gets data from the file system, and returns the product.

    [02:24 - 02:31] I'm actually using for this demonstration files as a database. But basically, that's something that communicates with the database.

    [02:32 - 02:40] This is server code, obviously. You cannot read the server files from the user's browser, hopefully, for security reasons.

    [02:41 - 02:52] So this is all server code. And we can see here that when I was trying to get the definition, I saw two things, "getProducts" and "rscGetProducts".

    [02:53 - 03:07] This is actually because I'm wrapping the "getProduct" code that communicates with the database within a cache. And there are actually two version, the "unstable_cache" and the "cache".

    [03:08 - 03:18] We will talk about the unstable version later on. It's more powerful, but as the name indicates, at the time I'm writing this course, it's unstable, but still very interesting.

    [03:19 - 03:24] We'll talk about that with tags and the revalidateTag function. Anyway, now, just focus on the cache.

    [03:25 - 03:37] It's important to cache this function because we might want to get those product lists in multiple components in the same page. And if we don't cache, it will trigger multiple requests to the database.

    [03:38 - 03:47] With a cache, we guarantee that if the product list is used on multiple components, it is still fetched only once in the database. So it's very important to cache the function.

    [03:48 - 04:10] And you can see this kind of trick I use here, I prefix all the functions that are safe to use in React server components with "rsc", React Server Component. So whenever I see a call with "rsc", I know that it's safe that I've wrapped the actual code within a cache.

    [04:11 - 04:19] So there are no performances issue and that I treat those are safe to render client-side. So this is how I get my product list.

    [04:20 - 04:30] The thing is that I'm still not really allowed to have an asynchronous components in React. First, I'm a wrap them with what we call a Suspense.

    [04:31 - 04:41] So the Suspense is just a component that will handle the fact that the underlying component is asynchronous. So we can see here that I have a product list that is not asynchronous.

    [04:42 - 04:49] It renders a Suspense with a fallback. It just show a loading text when the product list is loading.

    [04:50 - 04:54] We will never actually see it because we are using static rendering. So it's never loading actually in your application.

    [04:55 - 05:03] But anyway, it's there in case we move to dynamic rendering. And then it renders the asynchronous product list and the Suspense can do that.

    [05:04 - 05:07] It will handle that under the hood. At this point, you might worry about the security.

    [05:08 - 05:17] You are communicating directly to the database from React. That's really unsettling if you have been writing client-side, then you pass the data down to the client .

    [05:18 - 05:25] It's not very obvious where the client and the server limit cuts. The server being secure, the client being not secure.

    [05:26 - 05:40] So it can be a bit unsettling. Hopefully there is this great article from Sebastian Markbåge, who is a core Next.js contributor, that explains the architecture you can adopt to build your application safely.

    [05:41 - 05:53] And this is actually exactly what I'm doing with my "rscGetProduct". Whenever I prefix the "rscGetProduct", I'm creating a data layer that is separate from the rest of the application.

    [05:54 - 06:19] So if I want to audit the security of an application, I just need to check all those functions that start with "rsc" and verify that they get the right data. And this is actually as secure as an API or maybe even more secure because the bonus is that if you have internal APIs, in the past, you might have needed to make them public so client-side code could communicate with them.

    [06:20 - 06:37] No, you can keep them private, have a React Server Components to communicate with them, so server-side in a safe environment, and then only feed the client-side with those data. So it allows to make more APIs private and to focus on getting that in the Next.js application.