Material-ui样式在使用useMediaQuery钩子切换浅色/深色主题时被覆盖



我使用next.js和material-ui,并根据用户偏好更改主题。但似乎当切换到光模式时,样式(使用JSS)我设置将被覆盖,它只发生在使用光模式时,我甚至试图扭转两个主题,但它不起作用。经过多次尝试,我发现当更改系统/浏览器使用与useMediaQuery()钩子中设置的主题不同时,问题就会发生。const isInDarkMode = useMediaQuery("(prefers-color-scheme: dark)");(例如,当将preferences -color-scheme设置为深色时,浅色主题将导致样式被覆盖。)但我仍然不知道为什么会发生这种情况,以及如何避免。

编辑:手动设置isInDarkMode = false后,无论模式如何,样式都会被覆盖。所以可能useMediaQuery没有引起问题,但实际上解决了问题…?

编辑在我尝试将这个应用程序部署到vercel后,主页在所有颜色模式下都完全正常,一些由getStaticPaths()生成的页面仍然存在问题。

在iOS上的Safari和Windows上的Chrome上进行了测试,问题都出现了。

我用来设置主题的代码(我在_app.js中设置):
import Header from "../components/Header";
import React from "react";
import useMediaQuery from "@material-ui/core/useMediaQuery";
import { createTheme, ThemeProvider } from "@material-ui/core/styles";
import CssBaseline from "@material-ui/core/CssBaseline";
import "../styles/global.css";
function MyApp({ Component, pageProps }) {
const isInDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
const theme = React.useMemo(
() =>
createTheme({
spacing: 8,
palette: {
type: isInDarkMode ? "dark" : "light",
primary: {
main: isInDarkMode ? "#8A6BBE" : "#6F3381",
},
secondary: {
main: "#CB4042",
},
background: {
default: isInDarkMode ? "#1c1c1c" : "#fffffb",
},
},
typography: {
h3: {
fontFamily: "Source Serif Pro, serif",
fontWeight: "600",
fontSize: "2.2rem",
"@media (min-width:600px)": {
fontSize: "3rem",
},
},
},
}),
[isInDarkMode]
);
return (
<>
<ThemeProvider theme={theme}>
<CssBaseline />
<Header isInDarkMode={isInDarkMode} />
<Component {...pageProps} />
</ThemeProvider>
</>
);
}
export default MyApp;

(我试过不使用ememo,但没有解决问题)

const useStyles = makeStyles({
root: {
maxWidth: 345,
backgroundColor: "rgba(255, 255, 255, 0)",
border: "1px solid rgba(138, 107, 190, 0.7)",
borderRadius: "8px",
},
});

(以样式为例,问题将导致所有样式被覆盖,包括maxWidth, BackgroundColor和border/borderRadius)

问题解决了!这似乎是由于没有删除服务器端注入的CSS。我按照这里的教程

作为参考,这些是我的_document.js

import React from "react";
import Document, { Html, Head, Main, NextScript } from "next/document";
import { ServerStyleSheets } from "@material-ui/core/styles";
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head></Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with server-side generation (SSG).
MyDocument.getInitialProps = async (ctx) => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [
...React.Children.toArray(initialProps.styles),
sheets.getStyleElement(),
],
};
};

和_app.js

import Header from "../components/Header";
import React from "react";
import useMediaQuery from "@material-ui/core/useMediaQuery";
import { createTheme, ThemeProvider } from "@material-ui/core/styles";
import CssBaseline from "@material-ui/core/CssBaseline";
import { lightTheme, darkTheme } from "../utils/themes/Theme";
import "../styles/global.css";
function MyApp({ Component, pageProps }) {
const isInDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
React.useEffect(() => {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector("#jss-server-side");
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
return (
<ThemeProvider theme={isInDarkMode ? darkTheme : lightTheme}>
<CssBaseline />
<Header isInDarkMode={isInDarkMode} />
<Component {...pageProps} />
</ThemeProvider>
);
}
export default MyApp;

(我更改了在另一个文件中创建主题,但它应该是可选的)

最新更新