You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Next.js构建由CMS驱动的动态数据导航?

解决Next.js中API驱动全局导航的几种方案

方案一:在_app.js中使用客户端数据获取

直接在导航组件内通过useEffect发起API请求,拿到数据后渲染导航。这种方式简单易实现,适合对首屏导航渲染要求不高的场景。

示例代码:

// components/Navigation.js
import { useState, useEffect } from 'react';

export default function Navigation() {
  const [navLinks, setNavLinks] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchNavLinks() {
      try {
        const res = await fetch('你的CMS API端点地址');
        const data = await res.json();
        setNavLinks(data);
      } catch (err) {
        console.error('获取导航链接失败:', err);
      } finally {
        setLoading(false);
      }
    }
    fetchNavLinks();
  }, []);

  if (loading) {
    return <div>加载中...</div>; // 可替换为自定义加载组件
  }

  return (
    <nav>
      <ul>
        {navLinks.map(link => (
          <li key={link.id}>
            <a href={link.url}>{link.label}</a>
          </li>
        ))}
      </ul>
    </nav>
  );
}

之后在_app.js中导入该组件,即可在所有页面显示导航:

// _app.js
import Navigation from '../components/Navigation';

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Navigation />
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

方案二:使用getStaticProps结合增量静态生成

如果CMS导航数据更新有规律,可以用增量静态生成实现首屏有数据、后台自动更新的效果。可以封装一个复用的导航数据获取函数,在每个页面的getStaticProps中调用。

示例:

// lib/getNavProps.js
export async function getNavProps() {
  const res = await fetch('你的CMS API端点地址');
  const navLinks = await res.json();
  return { navLinks };
}

在页面中复用:

// pages/about.js
import Navigation from '../components/Navigation';
import { getNavProps } from '../lib/getNavProps';

export default function About({ navLinks }) {
  return (
    <>
      <Navigation links={navLinks} />
      <h1>关于我们</h1>
    </>
  );
}

export async function getStaticProps() {
  const navProps = await getNavProps();
  return {
    props: navProps,
    revalidate: 60, // 每60秒重新生成页面,拉取最新导航数据
  };
}

方案三:Next.js 13+ App Router 直接异步获取数据

如果你的项目用的是Next.js 13及以上的App Router,可以在根layout.js中直接用async/await获取数据——App Router支持服务器组件直接异步请求数据,无需额外处理。

示例:

// app/layout.js
async function fetchNavLinks() {
  const res = await fetch('你的CMS API端点地址', { cache: 'no-store' }); // no-store确保每次请求都拿最新数据
  if (!res.ok) {
    throw new Error('获取导航数据失败');
  }
  return res.json();
}

export default async function RootLayout({ children }) {
  const navLinks = await fetchNavLinks();

  return (
    <html lang="zh-CN">
      <body>
        <nav>
          <ul>
            {navLinks.map(link => (
              <li key={link.id}>
                <a href={link.url}>{link.label}</a>
              </li>
            ))}
          </ul>
        </nav>
        {children}
      </body>
    </html>
  );
}

方案四:用SWR/React Query做数据缓存与自动更新

如果需要更灵活的缓存、后台重新验证功能,可以用SWR或React Query这类数据请求库,它们能自动处理缓存、页面聚焦时重新拉取数据等场景。

以SWR为例:

// components/Navigation.js
import useSWR from 'swr';

const fetcher = async url => {
  const res = await fetch(url);
  return res.json();
};

export default function Navigation() {
  const { data: navLinks, error, isLoading } = useSWR('你的CMS API端点地址', fetcher, {
    revalidateOnFocus: true, // 页面聚焦时重新验证数据
    revalidateInterval: 30000, // 每30秒自动拉取一次最新数据
  });

  if (error) return <div>导航加载失败</div>;
  if (isLoading) return <div>加载中...</div>;

  return (
    <nav>
      <ul>
        {navLinks.map(link => (
          <li key={link.id}>
            <a href={link.url}>{link.label}</a>
          </li>
        ))}
      </ul>
    </nav>
  );
}

之后在_app.js中导入该组件即可,SWR会自动管理数据的更新与缓存。


内容的提问来源于stack exchange,提问作者Ayo Adesina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 02:05:18