Next.js 13: Data Fetching Issue with Prisma ORM - Old Data Displayed During Navigation Instead of Updated Data
Asked Answered
M

3

8

I am using Next.js 13 and Prisma ORM to fetch data within a server component and make it available to child components through a context. The route is structured as follows: /item/[id], and the id is utilized within the layout.tsx file to fetch data.

Upon the initial page load, data is fetched and made accessible to all child components through the context. However, I encounter an issue when modifying the data in the context (and updating it in the database via API calls). When navigating to a new page and then returning to the previous page, the old data is displayed from the initial load. The server-side function getChildItems, which should execute each time the page loads, only runs on a page refresh, but not during back and forth navigation. I could use router.refresh() from next/navigation when a change is made, but I don't think this is optimal.

Since this is a server component, I can't use hooks like useEffect. It would be possible to fetch the data in a client component from the api, but I want to render the page on the server if possible.

Here is my layout.tsx:

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

// This should run every time when navigating to /items/[id] but currently runs only on page refresh
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>
  );
}

I am sure Next.js is caching this page, but I have not found a way to invalidate the cache for a server component that actually works.

Thanks for your help in advance!

Edit: Here is the db code, if necessary:

import { PrismaClient } from "@prisma/client";
import { deletedAt } from "../prismaMiddleware";

declare global {
  // eslint-disable-next-line no-var
  var cachedPrisma: PrismaClient;
}

let prisma: PrismaClient;
if (process.env.NODE_ENV === "production") {
  prisma = new PrismaClient();
} else {
  if (!global.cachedPrisma) {
    global.cachedPrisma = new PrismaClient();
  }
  prisma = global.cachedPrisma;
}

prisma.$use(deletedAt);

export const db = prisma;
Manure answered 13/5, 2023 at 20:14 Comment(5)
can u post db codePinball
Did you check this out? nextjs.org/docs/app/building-your-application/data-fetching/…Ungracious
Yes, I tried export const revalidate = 0 and import { revalidateTag } from 'next/cache' but no luckManure
Having the exact same issue today. Hoping to get a response on this thread. Have you made any progress?Prudence
@Manure can you update your question and add how you implemented the NextJS revalidateTag?Ungracious
D
4

I believe you should use revalidatePath or revalidateTag when you perform the mutation, and remember that the revalidation doesn't happen right away, but at your next navigation to the revalidated segment.

Dyane answered 21/6, 2023 at 21:40 Comment(1)
Thanks! revalidatePath worked for me.Wei
M
2

You need to export a constant from the page.tsx to revalidate.

export const revalidate = 1; //revalidates every one second -- requires page reload
Meeks answered 21/7, 2023 at 12:20 Comment(0)
G
0

I had a similar issue in production, but I solved it using SWR. https://swr.vercel.app/docs/with-nextjs

In the file app/api/something.js

import { NextResponse } from "next/server";

export async function GET() {
  const something = await prisma.something.findMany();

  return NextResponse.json({ something });
}

in the view using

'use client';
import useSWR from "swr";

const fetcher = (...args) => fetch(...args).then((res) => res.json());

const App = () => {

  const { data, error, isLoading } = useSWR("/api/something", fetcher);
  
  return (
    ...
  )
}
Guido answered 3/11, 2023 at 20:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.