Next.js中如何一次性定义darkmode-js包并在多页面复用?
问题
我是Next.js新手,对代码结构有疑问。我有两个页面:PostList (index.js)和PostSingle ([postId].js),想要在两个页面中添加深色/浅色主题切换按钮,因此使用了darkmode-js包。该包的初始化代码如下:
const options = { bottom: "64px", right: "32px", left: "unset", time: "0.5s", mixColor: "#fff", backgroundColor: "#fff", buttonColorDark: "#100f2c", buttonColorLight: "#fff", saveInCookies: false, label: "🌓", autoMatchOsTheme: true, }; const darkmode = new Darkmode(options); darkmode.showWidget();
目前我在两个页面分别导入import Darkmode from "darkmode-js";,定义options并调用darkmode.showWidget();,示例如下:
import Darkmode from "darkmode-js"; const PostsList = (props) => { // All that package stuff here return ( ...
和
import Darkmode from "darkmode-js"; const PostsSingle = (props) => { // All that package stuff here return ( ...
但我认为这种结构不合理,请问有没有更好的方法可以一次性定义该包并在需要的地方复用?
解决方案
方法1:自定义Hook
将darkmode的初始化逻辑封装为自定义Hook,在需要的页面直接调用:
// hooks/useDarkmode.js import Darkmode from "darkmode-js"; export default function useDarkmode() { const options = { bottom: "64px", right: "32px", left: "unset", time: "0.5s", mixColor: "#fff", backgroundColor: "#fff", buttonColorDark: "#100f2c", buttonColorLight: "#fff", saveInCookies: false, label: "🌓", autoMatchOsTheme: true, }; const initDarkmode = () => { const darkmode = new Darkmode(options); darkmode.showWidget(); }; return { initDarkmode }; }
页面中使用示例:
// pages/index.js (PostList) import useDarkmode from "../hooks/useDarkmode"; import { useEffect } from "react"; const PostsList = (props) => { const { initDarkmode } = useDarkmode(); // 组件挂载时初始化主题切换 useEffect(() => { initDarkmode(); }, []); return ( // 页面内容 ); };
PostSingle页面只需同样导入该Hook并调用initDarkmode即可。
方法2:全局Layout组件(推荐)
如果你的页面有统一的布局容器,把darkmode初始化逻辑放在Layout组件中,所有使用该Layout的页面都会自动加载主题切换按钮:
// components/Layout.js import Darkmode from "darkmode-js"; import { useEffect } from "react"; const Layout = ({ children }) => { useEffect(() => { const options = { bottom: "64px", right: "32px", left: "unset", time: "0.5s", mixColor: "#fff", backgroundColor: "#fff", buttonColorDark: "#100f2c", buttonColorLight: "#fff", saveInCookies: false, label: "🌓", autoMatchOsTheme: true, }; const darkmode = new Darkmode(options); darkmode.showWidget(); }, []); return ( <div className="layout-container"> {/* 这里可以放导航栏、页脚等公共元素 */} {children} </div> ); }; export default Layout;
页面中用Layout包裹内容:
// pages/index.js import Layout from "../components/Layout"; const PostsList = (props) => { return ( <Layout> {/* PostList的页面内容 */} </Layout> ); };
这种方式无需每个页面单独处理,适合全局复用场景。
方法3:工具函数封装
将初始化逻辑抽成独立的工具函数,在需要的页面引入调用:
// utils/darkmode.js import Darkmode from "darkmode-js"; export const initDarkmode = () => { const options = { bottom: "64px", right: "32px", left: "unset", time: "0.5s", mixColor: "#fff", backgroundColor: "#fff", buttonColorDark: "#100f2c", buttonColorLight: "#fff", saveInCookies: false, label: "🌓", autoMatchOsTheme: true, }; const darkmode = new Darkmode(options); darkmode.showWidget(); };
页面中使用示例:
// pages/[postId].js import { initDarkmode } from "../utils/darkmode"; import { useEffect } from "react"; const PostsSingle = (props) => { useEffect(() => { initDarkmode(); }, []); return ( // 页面内容 ); };
内容的提问来源于stack exchange,提问作者Martin AJ
相关产品推荐
相关产品推荐

