我使用Next.js 13和Prisma ORM在服务器组件中获取数据,并通过上下文将其提供给子组件。路线结构如下:/item/[id]
,并且在layout.tsx文件中使用该id来获取数据。
在初始页面加载时,通过上下文获取数据并使其可供所有子组件访问。但是,当在上下文中修改数据(并通过API调用在数据库中更新数据)时,我遇到了一个问题。当导航到新页面然后返回到上一页面时,将显示初始加载时的旧数据。服务器端函数getChildItems
应该在每次页面加载时执行,它只在页面刷新时运行,而不是在来回导航期间运行。在进行更改时,我可以使用next/navigation
中的router.refresh()
,但我认为这不是最佳选择。
由于这是一个服务器组件,我不能使用像useEffect这样的钩子。可以从API获取客户端组件中的数据,但如果可能的话,我希望在服务器上呈现页面。
这是我的布局.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>
);
}
字符串
我确信Next.js正在缓存此页面,但我还没有找到一种方法来使实际工作的服务器组件该高速缓存无效。
提前感谢您的帮助!
编辑:如果需要,这里是db代码:
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;
型
2条答案
按热度按时间vkc1a9a21#
您需要从
page.tsx
导出一个常量以重新验证。字符串
cyej8jka2#
我认为在执行变异时应该使用
revalidatePath
或revalidateTag
,并记住重新验证不会立即发生,而是在下次导航到重新验证的片段时发生。