Next.js项目中通过Layout.js为不同页面配置不同导航栏
在Next.js中为不同页面配置不同导航栏
需求说明
我在Next.js项目中有2个导航栏组件(NavbarOne、NavbarTwo)和10个页面,希望通过Layout组件一次性为其中5个页面配置NavbarOne,剩余页面配置NavbarTwo。
现有代码问题
你当前的实现存在**重复渲染Layout(包括Footer)**的问题:_app.js已经给所有页面套了一层Layout,而_admission.js里又嵌套了一次Layout,会导致页面出现两个Footer。同时逐个页面手动传criteria不够高效,尤其是需要配置5个页面时。
推荐实现方案
下面提供两种更高效的实现方式,避免重复渲染,同时批量配置页面导航栏:
方案一:通过路由路径批量判断
在_app.js中根据当前页面的路由路径,决定给Layout传的criteria值,无需修改页面组件。
- 修改Layout.js(保留你的逻辑,无需额外改动)
import Footer from "../Footer"; import NavbarOne from "../Navbar/NavbarOne"; import NavbarTwo from "../Navbar/NavbarTwo"; const Layout = ({ children, criteria}) => { return ( <div> { criteria ? <NavbarOne /> : <NavbarTwo /> } {children} <Footer /> </div> ); } export default Layout;
- 修改_app.js
使用Next.js的useRouter钩子获取当前路由,定义需要使用NavbarOne的页面路径列表,动态判断criteria:
import Layout from '../components/layout/Layout'; import '../styles/styles.scss'; import { useRouter } from 'next/router'; function MyApp({ Component, pageProps }) { const router = useRouter(); // 定义需要使用NavbarOne的页面路径 const navbarOnePages = ['/', '/about', '/contact', '/services', '/blog']; // 判断当前页面是否在列表中 const useNavbarOne = navbarOnePages.includes(router.pathname); return ( <Layout criteria={useNavbarOne}> <Component {...pageProps} /> </Layout> ); } export default MyApp;
- 页面组件(比如_admission.js)无需嵌套Layout
直接写页面内容即可:
const Admission = () => { return ( <div> <h1>Admission</h1> </div> ); } export default Admission;
方案二:通过页面组件的静态属性配置
给需要使用特定导航栏的页面组件添加静态属性,在_app.js中读取该属性来判断。
- 修改Layout.js(同方案一)
- 修改_app.js
读取页面组件的静态属性useNavbarOne,默认使用NavbarTwo:
import Layout from '../components/layout/Layout'; import '../styles/styles.scss'; function MyApp({ Component, pageProps }) { // 默认使用NavbarTwo,页面如果指定useNavbarOne为true则用NavbarOne const useNavbarOne = Component.useNavbarOne || false; return ( <Layout criteria={useNavbarOne}> <Component {...pageProps} /> </Layout> ); } export default MyApp;
- 为需要使用NavbarOne的页面添加静态属性
比如index.js、about.js等页面:
const Home = () => { return ( <div> <h1>Home Page</h1> </div> ); } // 添加静态属性,指定使用NavbarOne Home.useNavbarOne = true; export default Home;
- 其他页面(比如_admission.js)无需添加属性
默认会使用NavbarTwo:
const Admission = () => { return ( <div> <h1>Admission</h1> </div> ); } export default Admission;
说明
- 两种方案都避免了页面嵌套Layout导致的重复渲染问题
- 方案一更适合批量按路径配置,方案二更灵活,可针对单个页面单独配置
- 选择哪种方案取决于你的页面路由结构和配置需求
内容的提问来源于stack exchange,提问作者Mahabub Hossain
相关产品推荐
相关产品推荐

