提问人:wongz 提问时间:11/17/2023 最后编辑:wongz 更新时间:11/17/2023 访问量:8
NextJS 13:使聊天应用程序中的侧边栏服务器组件失效
NextJS 13: Invalidating sidebar server component in chat app
问:
完整的最小可重现存储库在这里。
这是一个具有以下路线的聊天应用程序:
- /聊天
- layout.tsx - 包含服务器组件的服务器组件,该组件也是一个服务器组件
Sidebar
- layout.tsx - 包含服务器组件的服务器组件,该组件也是一个服务器组件
- /chat/[id] - 客户端组件
每当我更新组件中的数据时,即使使用以下所有命令,侧边栏也不会更新:Input
router.refresh();
router.push("/chat/" + chatId);
我什至有一个特殊的路由可以使服务器端的缓存失效,该缓存调用但侧边栏仍然没有更新。revalidatePath("/chat", "layout")
但是,这很奇怪,因为在我的服务器组件中,显示它更新了,但 UI 由于某种原因没有更新。Sidebar
下面是一些关键代码片段,但完整的可重现代码位于存储库中。
// ./app/chat/layout.tsx
import React from 'react'
import { Sidebar } from "./_sidebar"
export default async function Layout({children}: {children: React.ReactNode}) {
return (
<div className="relative w-screen min-h-screen flex justify-start">
<Sidebar />
{children}
</div>
)
}
// ./app/chat/_sidebar
import { getChats } from "@/actions";
import Link from "next/link";
export async function Sidebar() {
const chats = await getChats();
console.log("Sidebar.chats.latest", chats.at(-1))
return (
<div className="flex flex-col h-full px-6 min-h-screen">
<h2 className="font-bold underline">Sidebar</h2>
<Link href="/chat">New Chat</Link>
{chats.map((chat, index) => (
<p className="whitespace-nowrap" key={index}>{chat.message.slice(0,20)}</p>
))}
</div>
);
}
// ./app/chat/_input.tsx
"use client";
import { nanoid } from "nanoid";
import { useRouter } from "next/navigation";
import React from "react";
export function Input() {
const router = useRouter();
const inputRef = React.useRef<any>();
return (
<div className="absolute bottom-1/2 flex flex-col h-28">
<div className="flex flex-col space-y-8">
<label className="text-white">Input Field Below:</label>
<textarea ref={inputRef} className="text-black w-96 h-48" />
<button
className="bg-green-900 px-6 py-3"
onClick={async () => {
const value = inputRef?.current.value;
const chatId = nanoid();
await fetch("/api/chats/update", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ id: chatId, message: value }),
}).then(res => res.json());
await fetch(`/api/revalidate?path=/chat&type=layout`, {cache: "no-store"});
router.refresh();
router.push("/chat/" + chatId);
}}
>
Submit
</button>
</div>
</div>
);
}
答:
2赞
Muka Nakazato
11/23/2023
#1
我找到了一个解决方法:只需交换 和 行。
也许它不需要调用.router.push
router.refresh
revalidatePath
下面的代码是一个示例。
<button
className="bg-green-900 px-6 py-3"
onClick={async () => {
const value = inputRef?.current.value;
const chatId = nanoid();
await fetch("/api/chats/update", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ id: chatId, message: value }),
}).then(res => res.json());
router.push("/chat/" + chatId);
router.refresh();
}}
>
Submit
</button>
评论