React 19 + Next.js 15 中实现混合布局

发布于:2025-08-06 ⋅ 阅读:(32) ⋅ 点赞:(0)

在 React 19 + Next.js 15 中实现混合布局(全屏/带侧边栏)的推荐方案如下:


方案一:基于文件约定的布局系统(Next.js 15 推荐)

1. 创建布局文件夹结构
app/
├── (fullscreen)/          # 全屏页面组
│   ├── login/
│   │   └── page.js
│   └── landing/
│       └── page.js
├── (with-sidebar)/        # 带侧边栏页面组 
│   ├── dashboard/
│   │   └── page.js
│   └── settings/
│       └── page.js
├── layout.js              # 根布局
└── template.js            # 可复用的模板组件
2. 实现不同布局 (app/(fullscreen)/layout.js)
// 全屏布局
export default function FullscreenLayout({ children }) {
  return (
    <html lang="en" className="h-full">
      <body className="h-full">{children}</body>
    </html>
  );
}
3. 带侧边栏布局 (app/(with-sidebar)/layout.js)
import Sidebar from '@/components/Sidebar';
import Header from '@/components/Header';

export default function SidebarLayout({ children }) {
  return (
    <div className="flex flex-col min-h-screen">
      <Header />
      <div className="flex flex-1">
        <Sidebar />
        <main className="flex-1 p-6">{children}</main>
      </div>
    </div>
  );
}
4. 根布局 (app/layout.js)
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

方案二:基于条件渲染的布局组件

1. 创建动态布局组件
// components/LayoutSwitcher.js
'use client';

import { usePathname } from 'next/navigation';
import SidebarLayout from './SidebarLayout';
import FullscreenLayout from './FullscreenLayout';

export default function LayoutSwitcher({ children }) {
  const pathname = usePathname();
  const fullscreenPaths = ['/login', '/landing'];

  return fullscreenPaths.includes(pathname) ? (
    <FullscreenLayout>{children}</FullscreenLayout>
  ) : (
    <SidebarLayout>{children}</SidebarLayout>
  );
}
2. 修改根布局
// app/layout.js
import LayoutSwitcher from '@/components/LayoutSwitcher';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <LayoutSwitcher>{children}</LayoutSwitcher>
      </body>
    </html>
  );
}

方案三:使用 React 19 的元数据控制

1. 在页面中定义布局类型
// app/dashboard/page.js
export const layout = 'with-sidebar'; // 自定义元数据

export default function Dashboard() {
  return <div>Dashboard Content</div>;
}
2. 创建布局包装器
// app/LayoutWrapper.js
import { getPageLayout } from './getLayout';

export default function LayoutWrapper({ children, layoutType }) {
  const Layout = getPageLayout(layoutType);
  return <Layout>{children}</Layout>;
}

最佳实践建议

  1. CSS 处理

    /* globals.css */
    .fullscreen-page {
      @apply h-screen w-screen overflow-hidden;
    }
    
    .sidebar-layout {
      @apply flex min-h-screen;
    }
    
  2. 性能优化

    • 使用 React.cache() 记忆化布局组件
    • 对侧边栏使用 React.Suspense 延迟加载
  3. TypeScript 支持

    // types/layout.d.ts
    type LayoutType = 'fullscreen' | 'with-sidebar';
    
    declare module '*.page.js' {
      export const layout?: LayoutType;
    }
    
  4. 状态共享

    // 使用 React 19 Actions 处理布局状态
    const [layout, setLayout] = useActionState(
      (prev, newLayout) => newLayout,
      'with-sidebar'
    );
    

对比总结

方案 优点 缺点 适用场景
文件约定 原生支持,清晰隔离 需要目录重组 新项目
条件渲染 灵活控制 需要客户端渲染 已有项目改造
元数据 声明式配置 需要自定义逻辑 中型项目

选择方案一时,Next.js 15 的路由组功能可以保持URL路径不变((fullscreen)/login 实际访问路径仍是 /login


网站公告

今日签到

点亮在社区的每一天
去签到