In NextJS 13, how can I dynamically update data in a server-side rendered component? – Javascript

by
Ali Hasan
next.js next.js13 node.js reactjs

Quick Fix: For NextJS 13, dynamic data updates in server-side components are not yet supported. Workarounds involve defining route handlers or using pages/api for REST API routes.

The Problem:

In NextJS 13, a developer has a server-side rendered component that displays a list of categories. They also have a client-side component with an ‘Add’ button that triggers a modal for creating a new category. The developer needs to find the best approach to create a new category on the server from the client component and dynamically display the newly created category in the server-side component without reloading the entire page.

The Solutions:

Solution 1: Re-render Server Component

To dynamically update data in a server-side rendered component, you can re-render the component by using the `getStaticProps` method. This method is called every time the page is visited, so any changes made to the data will be reflected in the rendered page.

Here’s an example of how you can use getStaticProps to re-render a server-side component:

export async function getStaticProps() {
  const data = await fetch('https://api.example.com/data');
  return { props: { data } };
}

In this example, the getStaticProps method fetches data from an API and then returns the data as props to the server-side component. The server-side component can then use the props to render the data on the page.

If the data changes, you can simply re-run the getStaticProps method to fetch the latest data. This will cause the server-side component to be re-rendered with the updated data.

Solution 2: Server Actions and revalidatePath

You can achieve dynamic data updates in NextJS 13 server-side rendered components using server actions and revalidatePath.

Server actions are experimental features that enable asynchronous operations on the server side. Here’s how you can implement this approach:

  1. Enable Server Actions: Add this to next.config.js to activate server actions:
const nextConfig = {
  experimental: {
    serverActions: true,
  },
};
  1. Server Action: Create an action in categories/actions.ts. This action will handle creating a new category:
export async function createCategory(formData: FormData) {
  try {
    const name: string = formData.get('name') as string;
    const prisma: PrismaClient = new PrismaClient();
    const _category: Category = await prisma.category.create({
      data: {
        name,
      },
    });
  } catch (error: any) {
    throw new Error(error.message ?? 'An unexpected error occurred');
  } finally {
    revalidatePath('/categories');
  }
}
  1. Client-Side Form: Your AddCategoryForm will call this action upon submission:
export default function AddCategoryForm() {
  return (
    <form action={createCategory}>
      <input type="hidden" name="otherField" value="some value" />
      <label htmlFor="name">Add new</label>
      <input type="text" name="name" required/>
      <button type="submit">Add</button>
    </form>
  );
}
  1. Server-Side Component: In your server-side component, page.tsx, you’ll maintain your category list and use revalidatePath to trigger a refresh:
export default async function CategoriesPage() {
  const categories: Category[] = await getCategories();

  return (
    <div>
      <AddCategoryForm />
      
      <ul>
        {categories.map((category) => (
          <li key={category.id}>{category.name}</li>
        ))}
      </ul>
    </div>
  );
}
  1. revalidatePath: When the new category is created, revalidatePath will refresh the /categories URL, causing page.tsx to fetch the updated category list and re-render the page without a full refresh.

Q&A

What should I do if I am using NextJS for the first time and I want to dynamically display data in a server – rendered component?

To employ Prisma, define a route handler on the server (e.g., /api/route.ts or pages/api).

What is the solution if I want the newly posted data to be seamlessly added to the existing list without a full page reload?

You can achieve this using server actions and calling revalidatePath at the end of your action.

Video Explanation:

The following video, titled "Create Pages & Fetch Data in Next.js Using Static & Dynamic ...", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

Learn how to create static and dynamic routes in Next.js and fetch dynamic data to build a variety of pages. We'll use The Last Airbender ...