fix: use Link + router.refresh() for optimal navigation
Based on Next.js best practices research: - Use <Link> component for prefetching and client-side navigation - Add router.refresh() onClick to force server component re-render - This preserves SPA experience while ensuring fresh data - Fixes issue where pages don't reload after URL change
This commit is contained in:
parent
8e82b0ea99
commit
9aa1453f80
@ -1,4 +1,7 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
import { memo } from "react";
|
import { memo } from "react";
|
||||||
import { useChatVisibility } from "@/hooks/use-chat-visibility";
|
import { useChatVisibility } from "@/hooks/use-chat-visibility";
|
||||||
import type { Chat } from "@/lib/db/schema";
|
import type { Chat } from "@/lib/db/schema";
|
||||||
@ -37,6 +40,7 @@ const PureChatItem = ({
|
|||||||
onDelete: (chatId: string) => void;
|
onDelete: (chatId: string) => void;
|
||||||
setOpenMobile: (open: boolean) => void;
|
setOpenMobile: (open: boolean) => void;
|
||||||
}) => {
|
}) => {
|
||||||
|
const router = useRouter();
|
||||||
const { visibilityType, setVisibilityType } = useChatVisibility({
|
const { visibilityType, setVisibilityType } = useChatVisibility({
|
||||||
chatId: chat.id,
|
chatId: chat.id,
|
||||||
initialVisibilityType: chat.visibility,
|
initialVisibilityType: chat.visibility,
|
||||||
@ -45,7 +49,13 @@ const PureChatItem = ({
|
|||||||
return (
|
return (
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
<SidebarMenuButton asChild isActive={isActive}>
|
<SidebarMenuButton asChild isActive={isActive}>
|
||||||
<Link href={`/chat/${chat.id}`} onClick={() => setOpenMobile(false)}>
|
<Link
|
||||||
|
href={`/chat/${chat.id}`}
|
||||||
|
onClick={() => {
|
||||||
|
setOpenMobile(false);
|
||||||
|
router.refresh();
|
||||||
|
}}
|
||||||
|
>
|
||||||
<span>{chat.title}</span>
|
<span>{chat.title}</span>
|
||||||
</Link>
|
</Link>
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
|
|||||||
@ -174,21 +174,15 @@ export function TopNavbar({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* AI智能精选 */}
|
{/* AI智能精选 */}
|
||||||
<Button
|
<Link
|
||||||
variant="ghost"
|
href="/featured"
|
||||||
size="sm"
|
className="flex items-center gap-1 h-8 px-3 text-white hover:bg-white/15 hover:text-white rounded-full transition-colors text-sm font-medium"
|
||||||
className="flex items-center gap-1 h-8 px-3 text-white hover:bg-white/15 hover:text-white rounded-full transition-colors"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
router.push("/featured");
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
title="AI智能精选"
|
title="AI智能精选"
|
||||||
|
onClick={() => router.refresh()}
|
||||||
>
|
>
|
||||||
<Sparkles className="h-4 w-4 text-yellow-400" />
|
<Sparkles className="h-4 w-4 text-yellow-400" />
|
||||||
<span className="text-sm font-medium">AI精选</span>
|
<span>AI精选</span>
|
||||||
</Button>
|
</Link>
|
||||||
|
|
||||||
{/* 精选榜单 */}
|
{/* 精选榜单 */}
|
||||||
<DropdownMenu open={rankingOpen} onOpenChange={setRankingOpen}>
|
<DropdownMenu open={rankingOpen} onOpenChange={setRankingOpen}>
|
||||||
@ -259,39 +253,30 @@ export function TopNavbar({
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{/* 无限画布 */}
|
{/* 无限画布 */}
|
||||||
<Button
|
<button
|
||||||
variant="ghost"
|
className="flex items-center gap-1 h-8 px-3 text-white hover:bg-white/15 hover:text-white rounded-full transition-colors text-sm font-medium"
|
||||||
size="sm"
|
onClick={() => {
|
||||||
className="flex items-center gap-1 h-8 px-3 text-white hover:bg-white/15 hover:text-white rounded-full transition-colors"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
const newId = crypto.randomUUID();
|
const newId = crypto.randomUUID();
|
||||||
router.push(`/canvas/${newId}`);
|
router.push(`/canvas/${newId}`);
|
||||||
|
router.refresh();
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
title="无限画布"
|
title="无限画布"
|
||||||
>
|
>
|
||||||
<LayoutGrid className="h-4 w-4 text-purple-400" />
|
<LayoutGrid className="h-4 w-4 text-purple-400" />
|
||||||
<span className="text-sm font-medium">无限画布</span>
|
<span>无限画布</span>
|
||||||
</Button>
|
</button>
|
||||||
|
|
||||||
{/* 我的图册 */}
|
{/* 我的图册 */}
|
||||||
<Button
|
<Link
|
||||||
variant="ghost"
|
href="/gallery"
|
||||||
size="sm"
|
className="flex items-center gap-1 h-8 px-3 text-white hover:bg-white/15 hover:text-white rounded-full transition-colors text-sm font-medium"
|
||||||
className="flex items-center gap-1 h-8 px-3 text-white hover:bg-white/15 hover:text-white rounded-full transition-colors"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
router.push("/gallery");
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
title="我的图册"
|
title="我的图册"
|
||||||
|
onClick={() => router.refresh()}
|
||||||
>
|
>
|
||||||
<Images className="h-4 w-4" />
|
<Images className="h-4 w-4" />
|
||||||
<span className="text-sm font-medium">我的图册</span>
|
<span>我的图册</span>
|
||||||
</Button>
|
</Link>
|
||||||
|
|
||||||
{/* 分隔线 (如果有链接或图册按钮,且是管理员) */}
|
{/* 分隔线 (如果有链接或图册按钮,且是管理员) */}
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
@ -300,20 +285,14 @@ export function TopNavbar({
|
|||||||
|
|
||||||
{/* 系统设置(仅管理员可见)*/}
|
{/* 系统设置(仅管理员可见)*/}
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
<Button
|
<Link
|
||||||
variant="ghost"
|
href="/settings"
|
||||||
size="sm"
|
className="flex items-center justify-center h-8 w-8 text-white hover:bg-white/15 hover:text-white rounded-full"
|
||||||
className="h-8 w-8 p-0 text-white hover:bg-white/15 hover:text-white rounded-full"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
router.push("/settings");
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
title="系统设置"
|
title="系统设置"
|
||||||
|
onClick={() => router.refresh()}
|
||||||
>
|
>
|
||||||
<Settings className="h-4 w-4" />
|
<Settings className="h-4 w-4" />
|
||||||
</Button>
|
</Link>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user