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

如何在React组件中访问NextJS Cookie以控制导航栏链接显示?

解决方案

1. 客户端直接读取Cookie

写一个轻量的工具函数解析Cookie,在导航组件中直接判断认证Cookie是否存在:

// utils/cookie.js
export const getCookie = (name) => {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(';').shift();
};

然后在导航组件中使用:

import { getCookie } from '../utils/cookie';

const Navbar = () => {
  // 替换成你的认证Cookie键名,比如'auth_token'
  const isAuthenticated = !!getCookie('auth_token');

  return (
    <nav className="navbar">
      {/* 固定导航链接,比如首页 */}
      <a href="/">首页</a>
      
      {/* 未登录时显示登录/注册 */}
      {!isAuthenticated && (
        <>
          <a href="/login">登录</a>
          <a href="/register">注册</a>
        </>
      )}
      
      {/* 已登录时显示退出 */}
      {isAuthenticated && (
        <a href="/logout">退出登录</a>
      )}
    </nav>
  );
};

export default Navbar;

注意:纯客户端读取会有首次渲染闪烁的问题,因为客户端需要先完成Cookie解析,适合对体验要求不高的场景。

2. Server Components服务端读取(App Router)

如果用Next.js App Router,直接把导航栏改成Server Component,在服务端读取Cookie,彻底避免闪烁:

// app/components/Navbar.jsx
import { cookies } from 'next/headers';

const Navbar = () => {
  const authCookie = cookies().get('auth_token');
  const isAuthenticated = !!authCookie;

  return (
    <nav className="navbar">
      <a href="/">首页</a>
      {!isAuthenticated && (
        <>
          <a href="/login">登录</a>
          <a href="/register">注册</a>
        </>
      )}
      {isAuthenticated && (
        <a href="/logout">退出登录</a>
      )}
    </nav>
  );
};

export default Navbar;

这种方式在服务端直接获取Cookie,渲染完成后再返回给客户端,没有客户端渲染的延迟问题,是App Router的推荐方案。

3. getServerSideProps传递状态(Pages Router)

如果用Pages Router,在_app.js中通过getServerSideProps读取Cookie,把认证状态传递给所有页面:

// pages/_app.js
function MyApp({ Component, pageProps, isAuthenticated }) {
  return (
    <>
      <Navbar isAuthenticated={isAuthenticated} />
      <Component {...pageProps} />
    </>
  );
}

export async function getServerSideProps(context) {
  // 从请求头中读取Cookie
  const authCookie = context.req.cookies['auth_token'];
  return {
    props: {
      isAuthenticated: !!authCookie,
    },
  };
}

export default MyApp;

导航组件接收props后控制显示:

// components/Navbar.jsx
const Navbar = ({ isAuthenticated }) => {
  return (
    <nav className="navbar">
      <a href="/">首页</a>
      {!isAuthenticated && (
        <>
          <a href="/login">登录</a>
          <a href="/register">注册</a>
        </>
      )}
      {isAuthenticated && (
        <a href="/logout">退出登录</a>
      )}
    </nav>
  );
};

export default Navbar;

这种方式同样能避免客户端闪烁,适合Pages Router项目。

4. React Context管理全局认证状态

如果需要在多个客户端组件中共享认证状态(比如退出后同步更新UI),可以用Context封装:

// app/context/AuthContext.jsx
'use client';

import { createContext, useContext, useEffect, useState } from 'react';
import { getCookie } from '../utils/cookie';

const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    // 初始化时读取Cookie
    const authCookie = getCookie('auth_token');
    setIsAuthenticated(!!authCookie);
  }, []);

  // 封装退出方法,清除Cookie并更新状态
  const handleLogout = () => {
    document.cookie = 'auth_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
    setIsAuthenticated(false);
  };

  return (
    <AuthContext.Provider value={{ isAuthenticated, handleLogout }}>
      {children}
    </AuthContext.Provider>
  );
};

export const useAuth = () => useContext(AuthContext);

在根布局中包裹Provider:

// app/layout.js
import { AuthProvider } from './context/AuthContext';

export default function RootLayout({ children }) {
  return (
    <html lang="zh-CN">
      <body>
        <AuthProvider>{children}</AuthProvider>
      </body>
    </html>
  );
}

导航组件中使用Context:

// app/components/Navbar.jsx
'use client';

import { useAuth } from '../context/AuthContext';

const Navbar = () => {
  const { isAuthenticated, handleLogout } = useAuth();

  return (
    <nav className="navbar">
      <a href="/">首页</a>
      {!isAuthenticated && (
        <>
          <a href="/login">登录</a>
          <a href="/register">注册</a>
        </>
      )}
      {isAuthenticated && (
        <button onClick={handleLogout}>退出登录</button>
      )}
    </nav>
  );
};

export default Navbar;

内容的提问来源于stack exchange,提问作者shakil khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 21:39:20