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

