我正在使用 Material UI v4。
我尝试了类似 Ashkan 的回答,但对我不起作用。
但是,我在文档中找到了this,并将其抽象为适用于不同的状态,而不是用户偏好,这对我有用。对于您的示例,我可能会创建一个上下文:
// context.js
import React, { useContext } from "react";
import { ThemeProvider, createTheme } from "@material-ui/core/styles";
import CssBaseline from "@material-ui/core/CssBaseline";
const CustomThemeContext = React.createContext();
// You can add more to these and move them to a separate file if you want.
const darkTheme = {
palette: {
type: "dark",
}
}
const lightTheme = {
palette: {
type: "light",
}
}
export function CustomThemeProvider({ children }) {
const [dark, setDark] = React.useState(false);
function toggleTheme() {
if (dark === true) {
setDark(false);
} else {
setDark(true);
}
}
const theme = React.useMemo(
() => {
if (dark === true) {
return createTheme(darkTheme);
}
return createTheme(lightTheme);
},
[dark],
);
return (
<CustomThemeContext.Provider value={toggleTheme}>
<ThemeProvider theme={theme}>
<CssBaseline />
{children}
</ThemeProvider>
</CustomThemeContext.Provider>
);
}
export function useToggleTheme() {
const context = useContext(CustomThemeContext);
if (context === undefined) {
throw new Error("useCustomThemeContext must be used within an CustomThemeProvider");
}
return context;
}
然后将您的应用包装在其中:
ReactDOM.render(
<CustomThemeProvider>
<App />
</CustomThemeProvider>,
document.getElementById("app")
);
然后在您的应用中访问它:
export default function App(){
const toggleTheme = useToggleTheme();
return (
<div>
<button onClick={toggleTheme}>Toggle the theme!!</button>
</div>
);
}
附带说明一下,在我的应用程序中,我实际上在应用程序的两个部分中有不同的主题,具体取决于用户是否登录。所以我只是这样做:
function App() {
const { authState } = useAuthContext();
const theme = React.useMemo(
() => {
if (authState.user) {
return createTheme(dashboardTheme);
}
return createTheme(loginTheme);
},
[authState.user],
);
return (
<ThemeProvider theme={theme}>
<TheRestOfTheApp />
</ThemeProvider>
}
您似乎可以通过在 useMemo 中引用它们并将它们包含在依赖项数组中来将主题基于任何状态或多个状态。
编辑:
我刚刚注意到 MUI v5 实际上在他们的文档中有something very similar。