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

React结合Tailwind CSS与Catalyst UI Kit时,手动深色模式切换不生效的问题求助

React结合Tailwind CSS与Catalyst UI Kit时,手动深色模式切换不生效的问题求助

我现在在用最新版的Tailwind CSS,搭配Catalyst UI Kit开发组件。我注意到Catalyst的样式类里已经自带dark:前缀的深色模式样式了。为了实现主题切换,我自己创建了ThemeContext和一个切换按钮组件,用来存储light或dark的主题值,并且会把对应的类名加到HTML根元素上。

但现在遇到了一个头疼的问题:切换按钮看似正常工作——主题值能存在localStorage里,DOM根元素的class也确实跟着切换成light或dark了,但页面的样式完全没变化。不过如果我用系统或者Chrome自带的主题切换功能,页面样式是能正常响应的,只有我自己写的切换按钮不管用。

我已经检查了Tailwind的配置,也试了调整Context里的逻辑,甚至把index.html里预加载主题的脚本去掉也没用,实在没辙了,有没有大佬能帮我看看问题出在哪?

我的配置和代码:

tailwind.config.js

module.exports = {
  content: ["./src/**/*.{js,ts,jsx,tsx}"],
  darkMode: "class",
  theme: {
    extend: {},
  },
  plugins: [],
};

ThemeContext.tsx

import { createContext, useContext, useEffect, useState } from "react";

type Theme = "light" | "dark";

const ThemeContext = createContext<{
  theme: Theme;
  toggleTheme: () => void;
}>({
  theme: "light",
  toggleTheme: () => {},
});

export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
  const [theme, setTheme] = useState<Theme>("light");

  useEffect(() => {
    const stored = localStorage.getItem("theme");
    const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
    const resolved = stored === "dark" || (!stored && prefersDark) ? "dark" : "light";
    setTheme(resolved);
    document.documentElement.classList.remove("light", "dark");
    document.documentElement.classList.add(resolved);
  }, []);

  const toggleTheme = () => {
    const newTheme = theme === "dark" ? "light" : "dark";
    setTheme(newTheme);
    localStorage.setItem("theme", newTheme);
    document.documentElement.classList.remove("light", "dark");
    document.documentElement.classList.add(newTheme);
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {/* 强制主题变化时重新渲染子组件 */}
      <div key={theme}>{children}</div>
    </ThemeContext.Provider>
  );
};

export const useTheme = () => useContext(ThemeContext);

ThemeToggle.tsx

import { useTheme } from "../contexts/ThemeContext";

export default function ThemeToggle() {
  const { theme, toggleTheme } = useTheme();

  return (
    <button
      onClick={toggleTheme}
      className="fixed top-4 right-4 px-4 py-2 bg-zinc-200 dark:bg-zinc-700 text-black dark:text-white rounded"
    >
      {theme === "dark" ? "☀️ Light" : "🌙 Dark"}
    </button>
  );
}

App.tsx中的使用

function App() {
  return (
    <ThemeProvider>
      <AuthProvider>
        <Router>
          <AppRoutes />
        </Router>
      </AuthProvider>
    </ThemeProvider>
  );
}

export default App;

index.html中的预加载脚本

我原本在index.html里加了这段脚本,后来也试过删掉它,但问题依旧:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Vialis</title>
</head>
<body>
  <div id="root"></div>
  <script type="module" src="/src/main.tsx"></script>
  <script>
    const userTheme = localStorage.getItem("theme");
    const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
    if (userTheme === "dark" || (!userTheme && prefersDark)) {
      document.documentElement.classList.add("dark");
    } else {
      document.documentElement.classList.remove("dark");
    }
  </script>
</body>
</html>

我已经把能试的都试了,还是找不到问题所在,有没有大佬能指点一下?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 14:38:05