【教程】Next.js框架使用next-themes库实现主题切换

教程

首先,在app文件夹中创建一个ThemeWrapper.tsx[1][2]的客户端组件[3]

///ThemeWrapper.tsx
"use client";

import { ThemeProvider } from "next-themes";
import { ReactNode } from "react";

export default function ThemeWarpper({ children }: { children: ReactNode }) {
  return (
    //这里是因为tailwind的缘故才加这个属性,具体可以参考:https://github.com/pacocoursey/next-themes#with-tailwindcss
    <ThemeProvider attribute="class">
      {children}
    </ThemeProvider>
  );
}

然后在layout.tsx中使用这个组件

///简化的layout.tsx

import ThemeWarpper from "./ThemeWarpper";

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html>
      <body>
          <ThemeWarpper>{children}</ThemeWarpper>
      </body>
    </html>
  );
}

然后在全局的css中定义黑暗模式的样式

/* 简化的globals.css */
:root {
  /* Your default theme */
  --background: white;
  --foreground: black;
}

.dark {
  --background: black;
  --foreground: white;
}

然后就可以在组件中使用useTheme hook切换主题了

///Button.tsx
import { useTheme } from "next-themes";

export default function ThemeToggleButton() {
  const { theme, setTheme } = useTheme();
  
  const toggleTheme = () => {
    setTheme(theme === "dark" ? "light" : "dark");
  };
  
  return (
    <button onClick={toggleTheme}>
      点击切换主题
    </button>
  );
}

参考

本文的依赖为:

  • Next.js 1.5
  • react 19
  • typescript
  • tailwind

即Next.js 1.5框架脚手架的默认选项

想要了解更多,可以访问原项目

如果对各位有帮助的话可以在GitHub Gist上给我点点:star:

脚注


  1. 之所以不命名为ThemeProvider,是因为和next-themes的ThemeProvider命名冲突。 ↩︎

  2. Provider设计模式参考provider-pattern↩︎

  3. 后文layout.tsx是服务端组件,如果直接layout.tsx中使用next-themes的ThemeProvider(客户端组件),在测试环境可能是正常的,但是部署环境就会出些奇怪的错误,而且可能不报错,很难排查!所以一定要创建一个客户端组件然后导入。 ↩︎

1 Like

感谢大佬教程

1 Like

感谢教程,支持支持

1 Like

感谢教程

2 Likes