我在 React 应用程序中遇到主题切换问题。该应用程序支持两个主题,我将其称为主题一和主题二。我实现了延迟加载,根据所选主题动态加载相应的主题组件。
每个主题都为公共按钮类定义了自己的样式。例如,在主题一中,按钮为蓝色,而在主题二中,按钮为棕色。
当我使用按钮切换主题时就会出现问题。最初,当从主题一转换到主题二时,按钮颜色正确地从棕色更新为蓝色。然而,切换回主题一后,按钮颜色未能按预期恢复为棕色。后续的主题切换也不会反映按钮颜色的任何变化。
代码:https://codesandbox.io/p/devbox/wizardly-robinson-v774zf?file=%2Fsrc%2FDashboard.tsx%3A12%2C14
// App.js
import React, { createContext, useState, startTransition, useEffect } from "react";
// Lazy load themes
const ThemeOne = React.lazy(() => import("./themes/theme-one"));
const ThemeTwo = React.lazy(() => import("./themes/theme-two"));
export const MawbThemeContext = createContext({ _theme: "" });
const App = () => {
const [_theme, setTheme] = useState("themeOne");
const handleChangeTheme = () => {
startTransition(() => {
if (_theme === "themeOne") {
setTheme("themeTwo");
} else {
setTheme("themeOne");
}
});
};
let themeComponent;
if (_theme === "themeOne") {
themeComponent = <ThemeOne handleChangeTheme={handleChangeTheme} />;
} else if (_theme === "themeTwo") {
themeComponent = <ThemeTwo handleChangeTheme={handleChangeTheme} />;
} else {
themeComponent = <ThemeTwo handleChangeTheme={handleChangeTheme} />;
}
useEffect(() => {
startTransition(() => {
console.log("transition", _theme); // Ensure theme is changing correctly
});
}, [_theme]);
return (
<>
<MawbThemeContext.Provider value={{ _theme }}>
{themeComponent}
</MawbThemeContext.Provider>
</>
);
};
export default App;
我将不胜感激任何有关主题更新为何未正确反映的见解,特别是在主题之间多次转换时。
问题来自组件中的 css 导入行
import "../scss/index.theme.one.scss";
import "../scss/index.theme.two.scss";
如果您检查应用程序中呈现的 HTML,您可以看到以下行为。
您的应用程序第一次启动时,仅调用了 ThemeOne 组件,因此如果您检查 css,您将看到仅加载了第一个:
但是,一旦您切换主题,就会调用第二个导入行,这意味着调用第二个 css 文件:
此时,你可以随意切换,第二个css文件领先于第一个,这就是为什么你不能再得到你的棕色按钮了。
要解决此问题,您必须处理通过组件传递的 context。
例如,使用钩子获取当前上下文并应用正确的 css 属性。一个例子这里