如何在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
相关产品推荐
相关产品推荐

