NextJS侧边栏如何在主内容上推送路由

问题描述 投票:0回答:2

我在 NextJS 应用程序中有一个侧边栏,并且有一个主要组件放置在一行中。侧边栏有多个项目,单击每个项目会通过推送路线(更新 url)来更新主要内容

<Preview/>
,但这会重新渲染侧边栏和主要内容。我的理解是组件放置不正确导致了问题。现在我已将侧边栏和主要组件放置在
<Home/>

文件夹结构和组件结构应该如何?考虑到 Main 组件是一个动态组件(根据传递给它的 id 进行渲染)。

这是文件夹结构

文件夹结构

project-root /
    ├──src
    │    ├── app /
    │    │   ├── models /
    │    │   │   ├── Log.ts
    │    │   ├── services /
    │    │   │   ├── LogService.ts
    │    │   ├── components /
    │    │   │   ├── Sidebar.tsx
    │    │   │   ├── Navbar.tsx
    │    │   │   ├── Preview.tsx
    │    │   │   └── Home.tsx
    │    │   │   │
    │    │   ├── logs /
    │    │   │   ├──[id]
    │    │   │   │   ├── page.tsx
    │    │   └── layout.tsx
    │    │   └── global.css
    │    │   └── page.tsx

这是动态页面

logs/[id]/page.tsx

// logs/[id]/page.tsx
import Home from '@/app/_components/Home';
import LogService from '../../_services/logService';

// This is required for dynamic routing in runtime
export const dynamicParams = true;

export async function generateStaticParams() {
    const logService = new LogService();
    const logs = await logService.fetchLogs();
    return logs.map(log => ({ id: log.id }));
}

export default function Page({ params }: { params: { id: string } }) {
    const { id } = params;
    return <Home id={id} />
};
// _components/Home.tsx

"use client";

import IconButton from "./IconButton";
import PSNavbar from "./PSNavbar";
import Pastelog from "./Pastelog";
import Preview from './Preview';
import Sidebar from './Sidebar';
import { Theme } from './ThemeSwitcher';

export default function Home({ id }: { id: string | null }) {
    const [showSideBar, setShowSideBar] = useState<boolean>(true);
    const [logs, setLogs] = useState<Log[]>([]);
    const [loading, setLoading] = useState<boolean>(false);
    const [selectedLogId, setSelectedLogId] = useState<string | null>(id);

...

    return (
        <div className={`flex h-screen ${theme == Theme.DARK ? 'darkTheme' : 'lightTheme'}`}>
            {
                (showSideBar && <IconButton
                    onClick={() => setShowSideBar(!showSideBar)}>
                    <ViewSidebarRoundedIcon />
                </IconButton>
                )
            }

            <div>
                {showSideBar && (
                    <Sidebar
                        loading={loading}
                        logs={logs}
                        id={selectedLogId}
                        onLogClick={(id) => {
                            if (id) {
                                router.push('/logs/$id');
                                setSelectedLogId(id!);
                            } else {
                                setSelectedLogId(null);
                                router.push('/');
                            }
                        }}
                    />
                )}
            </div>

            {/* Main content */}
            <div className={`grow overflow-y-auto transition-all duration-800 ${showSideBar ? 'pl-64' : 'pl-0'}`}>
                <div className="flex flex-col h-full">
                    <PSNavbar
                        sideBarIcon={!showSideBar}
                        onToggleSidebar={() => setShowSideBar(!showSideBar)}
                    />
                    {
                        selectedLogId ? (<Preview
                            id={selectedLogId}
                            showNavbar={false}
                        />) :
                            (<Pastelog />)
                    }
                </div>
            </div>
        </div>
    );
}

这种方法的问题是我想在侧边栏中选择列表项时更新 url 它可以工作,但这会触发整个主页的重新渲染(预期),但我希望只渲染主要内容.

此外,如果用户通过链接访问网站

<baseurl>/sidebar-item
,我希望应用程序能够加载选定的侧边栏项目(目前工作正常)

完整源代码在这里

这是上述代码的输出,显示侧边栏重新渲染

enter image description here

next.js web-applications navigation next-router
2个回答
1
投票

如果侧边栏内容对于所有页面都是通用的,那么您可以将侧边栏组件移动到布局文件中。 例如:

export default function Layout ({ children } : { children : React.ReactNode}) {
 return <>
  <Sidebar />
  {children} //page content will go here
 </>
} 

0
投票

您正在使用路由器,它用于重新渲染整个应用程序并重定向到所需的页面。我建议使用组件来简单地切换组件。

© www.soinside.com 2019 - 2024. All rights reserved.