[Fixed] Next.js 13: Data Fetching Issue with Prisma ORM – Old Data Displayed During Navigation Instead of Updated Data – Next.js

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

Quick Fix: To resolve this issue, use revalidatePath or revalidateTag when performing the mutation, ensuring revalidation occurs during the next navigation to the revalidated segment. This ensures that the updated data is fetched and displayed correctly.

The Problem:

In Next.js 13 with ORM, when updating data in a server component and navigating between pages, the old data is displayed instead of the updated data. The getChildItems function, which fetches data, runs only on page refresh and not during back and forth navigation. Caching is suspected to be the cause, but invalidating the cache for a server component is proving to be challenging.

The Solutions:

Solution: Invalidate Cache

To address the issue of cached data being displayed during navigation, you can invalidate the cache after updating the data in the context and API. Next.js provides the `revalidatePath` or `revalidateTag` options for server components, which can be used to instruct Next.js to invalidate the cache for specific paths or tags.

When performing the mutation, use `revalidatePath` or `revalidateTag` to specify the path or tag that should be invalidated. This will trigger Next.js to revalidate the data on the next navigation to the specified path or tag, ensuring that the updated data is displayed.

Note that the revalidation doesn’t happen immediately but rather on the next navigation to the revalidated segment. This allows Next.js to optimize the revalidation process and avoid unnecessary revalidations on every request.

Solution 2: Revalidate on Page Load

Export a constant named `revalidate` from the page component to revalidate the data on every page load. This will cause the page to reload and fetch the updated data. Here’s how you can implement it:

// page.tsx
import { Item } from "@prisma/client";
import { ListProvider } from "~/context/list-context";
import { db } from "~/lib/db"; // Prisma ORM database connection

async function getChildItems(itemId: Item["id"]) {
  return await db.item.findMany({
    where: {
      parent_id: itemId,
    },
  });
}

export default async function ListLayout(params) {
  const items = await getChildItems(params.id);

  return (
    <ListProvider listId={params.id} items={items}>
      <div>{children}</div>
    </ListProvider>
  );
}

export const revalidate = 1; // Revalidate every second on page load

Note that `revalidate` must be set to a number representing the desired revalidation interval (in seconds). Setting it to `1` will revalidate on every request to the page.

Solution 3: Use SWR for Data Fetching

Implement a data fetching strategy using SWR (a React data fetching library) to ensure that the most up-to-date data is always available. This will handle caching and data invalidation automatically, eliminating the need for manual cache management.

Q&A

How to avoid caching issues on server components?

Use revalidatePath or revalidateTag when you perform the mutation and export a constant from the page.tsx to revalidate.

Can you provide an example of using SWR to solve data fetching issues?

You can use fetcher within SWR to fetch data in the client-side and pass it as a prop to the component.

Video Explanation:

The following video, titled "Handle new data when using SSR WITHOUT refreshing the page ...", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

Using SSR is one of my favorite features of Next.js but sometimes your data is updated outside of your application or even in it and the SSR ...