Next.js SSR求助:电商站导航菜单服务端获取跨页面复用方案
解决方案
1. 服务端全局获取 + React Context 共享(动态数据场景)
如果你的导航菜单需要实时更新,可以在自定义_app.js中通过getServerSideProps统一获取数据,再通过React Context传递给所有页面组件,实现一次获取全局复用:
- 第一步:创建导航数据的Context
// contexts/NavContext.js import { createContext, useContext } from 'react'; const NavContext = createContext(); export function NavProvider({ children, navData }) { return ( <NavContext.Provider value={navData}> {children} </NavContext.Provider> ); } export function useNav() { return useContext(NavContext); }
- 第二步:在
_app.js中获取数据并注入Context
// pages/_app.js import { NavProvider } from '../contexts/NavContext'; export async function getServerSideProps() { // 服务端请求导航菜单数据,替换为你的实际接口 const res = await fetch('你的导航菜单API地址'); const navData = await res.json(); return { props: { navData } }; } function MyApp({ Component, pageProps, navData }) { return ( <NavProvider navData={navData}> <Component {...pageProps} /> </NavProvider> ); } export default MyApp;
- 第三步:在任意组件中直接调用
// components/Navbar.js import { useNav } from '../contexts/NavContext'; export default function Navbar() { const navData = useNav(); return ( <nav> {navData.map(item => ( <a key={item.id} href={item.path}>{item.name}</a> ))} </nav> ); }
2. 静态生成场景:根布局中直接获取(Next.js 13+ App Router)
如果导航菜单是静态数据(不常更新),在App Router的根layout.js中直接写服务端请求逻辑即可——根布局是服务器组件,默认在服务端执行,数据会在页面构建或请求时获取,所有子页面都能复用:
// app/layout.js async function fetchNavData() { // 开启缓存,避免重复请求 const res = await fetch('你的导航菜单API地址', { cache: 'force-cache' }); return res.json(); } export default async function RootLayout({ children }) { const navData = await fetchNavData(); return ( <html lang="zh-CN"> <body> <Navbar navData={navData} /> {children} </body> </html> ); }
3. 构建时生成静态文件(完全静态数据场景)
如果导航菜单几乎不会更新,可以在构建前把数据写入本地JSON文件,之后直接在组件中导入使用:
- 第一步:写一个预构建脚本获取数据
// scripts/fetch-nav-data.js const fs = require('fs'); const fetch = require('node-fetch'); async function main() { const res = await fetch('你的导航菜单API地址'); const navData = await res.json(); fs.writeFileSync('./public/nav-data.json', JSON.stringify(navData)); } main();
- 第二步:在
package.json中添加预构建命令
{ "scripts": { "prebuild": "node scripts/fetch-nav-data.js", "build": "next build" } }
- 第三步:组件中直接导入使用
// components/Navbar.js import navData from '../public/nav-data.json'; export default function Navbar() { return ( <nav> {navData.map(item => ( <a key={item.id} href={item.path}>{item.name}</a> ))} </nav> ); }
内容的提问来源于stack exchange,提问作者usman naeem
相关产品推荐
相关产品推荐

