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

Next.js集成Material UI时动态样式失效、类名不匹配问题

问题原因

你遇到的className did not match报错本质是Next.js服务端渲染生成的类名,和客户端hydrate时生成的类名序号不一致,MUI v4的makeStyles接收动态props生成样式时,默认自动生成类名前缀,服务端和客户端渲染顺序差异会导致序号偏移,出现重复类名、样式不生效的问题。热更新时仅走客户端渲染逻辑,所以不会触发该问题。

解决方案

方案1:替换为MUI官方更适配动态props的styled API(推荐)

styled API对SSR场景的动态样式兼容性更好,不需要额外处理类名生成规则,重写你的CustomButton组件即可:

import React from "react";
import PropTypes from "prop-types";
import { styled } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";

const CustomButton = styled(Button)(({ theme, color }) => ({
  background: theme.palette[color].main,
  height: 48,
  padding: "0 30px",
  margin: 8,
}));

CustomButton.propTypes = {
  color: PropTypes.oneOf(["blue", "red", "green", "yellow"]).isRequired,
};

export default CustomButton

方案2:给makeStyles添加固定类名前缀

如果要保留makeStyles的写法,给makeStyles传入第二个配置参数,固定类名前缀,避免服务端客户端序号不一致:

const useStyles = makeStyles((theme) => ({
  root: {
    background: (props) => theme.palette[props.color].main,
    height: 48,
    padding: "0 30px",
    margin: 8,
  },
// 新增name配置固定类名前缀
}), { name: 'CustomButton' });

必查项:确认_document.js配置符合MUI SSR要求

必须在项目的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'; // 替换为你的theme文件路径

export default class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <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()],
  };
};
额外优化

你当前CustomButton的propTypes只声明了blue、red两个可选值,实际使用了green、yellow,建议补全propTypes的枚举值,避免无效prop警告。


内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:36:02