You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js搭配Material UI时向makeStyles传参出现className不匹配问题

问题根因
  • 类名不匹配报错:你配置的styled-components SSR规则对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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 16:27:02