Next.js App Router中全局状态(暗黑模式等)该如何放置?
解决Next.js App Router的两个核心问题
1. 全局复用Nav和Footer组件
在App Router中,根layout.js是所有页面的共享布局,无需在每个page.js中重复引入组件,直接把Nav和Footer放到根布局即可:
// app/layout.js import Nav from './components/Nav'; import Footer from './components/Footer'; export default function RootLayout({ children }) { return ( <html lang="zh-CN"> <body> <Nav /> {/* children会自动渲染各个页面的内容(首页page.js、联系页contact/page.js) */} <main>{children}</main> <Footer /> </body> </html> ); }
不管是首页还是联系页,都会自动继承这个布局,无需单独处理组件复用。
2. 在layout中管理暗黑模式状态并给html添加dark类
App Router的根layout默认是服务器组件,需用客户端组件处理状态逻辑,结合React上下文实现全局状态共享:
步骤1:创建ThemeProvider客户端组件
// app/components/ThemeProvider.jsx 'use client'; import { createContext, useContext, useState, useEffect } from 'react'; const ThemeContext = createContext(); export function ThemeProvider({ children }) { // 初始化状态:优先取localStorage的保存值,默认浅色模式 const [isDarkMode, setIsDarkMode] = useState(() => { if (typeof window !== 'undefined') { return localStorage.getItem('darkMode') === 'true'; } return false; }); // 同步状态到html元素的class useEffect(() => { const html = document.documentElement; isDarkMode ? html.classList.add('dark') : html.classList.remove('dark'); localStorage.setItem('darkMode', isDarkMode); }, [isDarkMode]); // 切换暗黑模式的函数 const toggleDarkMode = () => setIsDarkMode(prev => !prev); return ( <ThemeContext.Provider value={{ isDarkMode, toggleDarkMode }}> {children} </ThemeContext.Provider> ); } // 自定义hook,方便组件调用上下文 export function useTheme() { return useContext(ThemeContext); }
步骤2:在根layout中引入ThemeProvider
修改根layout,用ThemeProvider包裹所有内容:
// app/layout.js import Nav from './components/Nav'; import Footer from './components/Footer'; import { ThemeProvider } from './components/ThemeProvider'; export default function RootLayout({ children }) { return ( <html lang="zh-CN"> <body> <ThemeProvider> <Nav /> <main>{children}</main> <Footer /> </ThemeProvider> </body> </html> ); }
步骤3:在Nav组件中调用切换函数
在Nav组件里通过自定义hook获取切换能力:
// app/components/Nav.jsx 'use client'; import { useTheme } from './ThemeProvider'; export default function Nav() { const { isDarkMode, toggleDarkMode } = useTheme(); return ( <nav> {/* 其他导航内容 */} <button onClick={toggleDarkMode}> {isDarkMode ? '切换到浅色模式' : '切换到暗黑模式'} </button> {/* 语言切换组件 */} </nav> ); }
步骤4:配置Tailwind支持class模式
确保tailwind.config.js中设置darkMode为'class':
/** @type {import('tailwindcss').Config} */ module.exports = { darkMode: 'class', // 其他配置... }
这样就能实现全局暗黑模式状态管理,html元素会自动添加/移除dark类,Tailwind的暗黑模式样式也会正常生效。
内容的提问来源于stack exchange,提问作者Santi
相关产品推荐
相关产品推荐

