Next.js集成Material UI时makeStyles传参报错及生产环境媒体查询失效
问题1:向makeStyles传递props时报错
原因
- 语法错误:
makeStyles的配置对象多了一个多余的闭合大括号,导致语法解析失败 - 缺失样式定义:代码中使用了
classes.btnContainer,但makeStyles内未声明对应的样式类 - TypeScript类型不匹配:未给
makeStyles声明接收的props类型,ts校验不通过
解决方法
修正后的代码如下:
import { Theme, makeStyles } from "@material-ui/core/styles"; // 声明传递给样式的props类型 interface StyleProps { open: boolean; } const useStyles = makeStyles<Theme, StyleProps>((theme: Theme) => ({ root: { background: "#EFEFEF", minHeight: (props) => props.open ? "150vh" : "100vh", }, // 补上你用到的btnContainer样式定义 btnContainer: { display: "flex", gap: "16px", // 其他你需要的样式 } }));
问题2:生产环境中theme.breakpoints.down("sm")规则不生效
原因
ServerStyleSheets导入路径错误,MUI v4正确路径为@material-ui/core/styles,你当前的导入路径会导致服务端渲染的样式生成异常_document.tsx的getInitialProps中finally块的ctx.renderPage(sheet)是多余代码,不符合官方集成规范,会导致服务端与客户端样式不一致- 未配置jss样式注入顺序,生产环境下MUI默认样式优先级高于自定义样式,覆盖了媒体查询规则
解决方法
- 修正
_document.tsx的导入和冗余代码:
// 修正导入路径 import { ServerStyleSheets } from "@material-ui/core/styles"; import Document, { Html, Head, Main, NextScript } from "next/document"; class MyDocument extends Document { static async getInitialProps(ctx: any) { const sheet = new ServerStyleSheets(); const originalRenderPage = ctx.renderPage; try { ctx.renderPage = () => originalRenderPage({ enhanceApp: (App: any) => (props: any) => sheet.collect(<App {...props} />), }); const initialProps = await Document.getInitialProps(ctx); return { ...initialProps, styles: ( <> {initialProps.styles} {sheet.getStyleElement()} </> ), }; } finally { // 删除多余的ctx.renderPage(sheet)代码 } } // 剩余render代码保持不变 } export default MyDocument;
- 在
_app.tsx中添加StylesProvider配置,调整样式注入顺序:
import { StylesProvider } from "@material-ui/core/styles"; // 其他导入保持不变 class MyApp extends App<any> { componentDidMount() { const jssStyles = document.querySelector("#jss-server-side"); if (jssStyles) { jssStyles.parentElement!.removeChild(jssStyles); } } render() { const { Component, pageProps, apolloClient } = this.props; return ( <> <Head> <title>Beauty wall spot</title> <meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" /> </Head> {/* 新增StylesProvider,设置injectFirst让自定义样式优先级更高 */} <StylesProvider injectFirst> <ThemeProvider theme={theme}> <CssBaseline /> <ApolloProvider client={apolloClient}> <Component {...pageProps} /> </ApolloProvider> </ThemeProvider> </StylesProvider> </> ); } } export default withApollo(MyApp);
- 如果你自定义过theme的断点配置,确认
sm断点的阈值符合你的预期,MUI v4默认sm断点为600px,theme.breakpoints.down("sm")对应的媒体查询是max-width: 599.95px。
内容的提问来源于stack exchange,提问作者sumukha kb
相关产品推荐
相关产品推荐

