Next.js搭配Material UI时向makeStyles传参出现className不匹配问题
问题根因
- 类名不匹配报错:你配置的
styled-componentsSSR规则对Material UI的makeStyles完全无效,二者是独立的样式方案。Next.js SSR场景下服务端和客户端生成的MUI类名序号不一致,才导致该报错。 - display属性不生效:你当前贴出的代码仅给搜索Icon绑定了
classes.searchButton类,需要控制显隐的搜索栏DOM元素没有绑定对应的classes.search类,动态样式自然不会生效。
解决方案
第一步:修复类名不匹配问题
首先删除你新增的.babelrc文件,该配置和你当前使用的MUI样式方案无关,避免额外干扰。
如果你使用的是MUI v4,需要在Next.js项目的pages目录下新建_document.js文件,加入MUI SSR样式适配逻辑:
import Document, { Html, Head, Main, NextScript } from 'next/document' import { ServerStyleSheets } from '@material-ui/core/styles' import theme from '../path/to/your/theme' // 替换为你实际的MUI主题文件路径 export default class MyDocument extends Document { render() { return ( <Html lang="zh"> <Head> <meta name="theme-color" content={theme.palette.primary.main} /> </Head> <body> <Main /> <NextScript /> </body> </Html> ) } } MyDocument.getInitialProps = async (ctx) => { 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: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()], } }
如果你使用的是MUI v5,makeStyles已经是废弃的legacy API,建议直接替换为sx属性或者styled方案,天然适配Next.js SSR,不需要额外配置_document.js。
第二步:修复动态显隐不生效问题
给你需要控制显示隐藏的搜索栏元素绑定classes.search类,示例如下:
const Navbar = () => { const [open, setOpen] = useState(false); const classes = useStyles({ open }); return ( <> {/* 搜索栏元素,必须绑定classes.search */} <div className={classes.search}> {/* 搜索栏的具体内容 */} </div> {/* 你原来的搜索图标 */} <Search className={classes.searchButton} onClick={() => setOpen(true)} /> </> ) }
可选兼容方案
如果你的MUI版本较低不支持makeStyles传动态props的写法,可以用clsx库动态拼接类名实现同样效果:
import clsx from 'clsx' const useStyles = makeStyles((theme) => ({ search: { [theme.breakpoints.down('sm')]: { width: '70%', }, }, searchHidden: { [theme.breakpoints.down('sm')]: { display: 'none', }, }, searchShow: { [theme.breakpoints.down('sm')]: { display: 'flex', }, } })) // 组件内使用 const classes = useStyles() const searchClass = clsx(classes.search, open ? classes.searchShow : classes.searchHidden)
内容的提问来源于stack exchange,提问作者jeril
相关产品推荐
相关产品推荐

