Server-side component

Framework Next.js 13 Data Sharing: Server-side component

Sharing data between Server Components

Server Components are not interactive and therefore DO NOT read from React state

You can use native JavaScript patterns like global singletons within module scope if you have common data that multiple Server Component need to access.

1. Create the singleton variable

// utils/database.js
export const db = new DatabaseConnection(...);

2. Access singleton variable from different server-side component

// app/users/layout.js
import { db } from "@utils/database";

export async function UsersLayout() {
  let users = await db.query(...);
  // ...
}
// app/users/[id]/page.js
import { db } from "@utils/database";

export async function DashboardPage() {
  let user = await db.query(...);
  // ...
}

Sharing fetch requests between Server Components

We recommend fetching data directly inside the layout that needs it, even if you’re requesting the same data multiple times in a route. Behind the scenes, React and Next.js will cache and dedupe requests to avoid the same data being fetched more than once.

POST requests are not automatically deduplicated.

If you’re unable to use fetch, React provides a cache function to allow you to manually cache data for the duration of the request.

Per-request Caching

1. Wrapped the get data function inside the cache function

// utils/getUser.ts
import { cache } from 'react';

export const getUser = cache(async (id: string) => {
  const user = await db.user.findUnique({ id });
  return user;
});

2. Access the same get data function in different components

Only one query will be made to the database. This is because getUser() is wrapped in cache(), so the second request can reuse the result from the first request.

// app/user/[id]/layout.tsx
import { getUser } from '@utils/getUser';

export default async function UserLayout({ params: { id } }) {
  const user = await getUser(id);
  // ...
}
// app/user/[id]/page.tsx
import { getUser } from '@utils/getUser';

export default async function UserLayout({
  params: { id },
}: {
  params: { id: string };
}) {
  const user = await getUser(id);
  // ...
}

Recommend to fetching data directly in the component that needs it, even if you’re requesting the same data in multiple components instead of prop drilling.

Recommend using the server-only package to make sure server data fetching functions are not accidentally used on the client.

Reference