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

Next.js SSR模式下外部组件样式无法生效问题求助

Next.js SSR下Material-UI makeStyles样式不生效的解决方案

你遇到的问题是因为Material-UI的makeStyles生成的样式在Next.js服务端渲染阶段没有被注入到HTML中,导致首次SSR页面无样式,客户端hydration后才恢复正常。以下是具体解决步骤:

1. 配置自定义_document.js收集服务端样式

在pages目录下新建或修改_document.js,用于在SSR时收集并注入Material-UI样式:

// pages/_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '@mui/styles';
import React from 'react';

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheets = new ServerStyleSheets();
    const originalRenderPage = ctx.renderPage;

    try {
      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()],
      };
    } finally {
      ctx.renderPage = originalRenderPage;
    }
  }

  render() {
    return (
      <Html lang="zh-CN">
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

2. 在_app.js中提供主题上下文

确保全局组件树能获取到Material-UI主题,避免样式生成时缺少主题配置:

// pages/_app.js
import { ThemeProvider } from '@mui/styles';
import { createTheme } from '@mui/material/styles';
import React from 'react';

// 主题配置需和组件中使用的断点、spacing保持一致
const theme = createTheme({
  breakpoints: {
    values: {
      xs: 0,
      sm: 600,
      md: 900,
      lg: 1200,
      xl: 1536,
    },
  },
});

export default function MyApp({ Component, pageProps }) {
  return (
    <ThemeProvider theme={theme}>
      <Component {...pageProps} />
    </ThemeProvider>
  );
}

3. 修正组件和样式的使用方式

makeStyles返回的是一个Hook,需要在组件内调用获取classes,检查你的代码是否正确:

// 组件文件
import AppBar from '@mui/material/AppBar';
import clsx from 'clsx';
import { useStyles } from './path-to-your-styles';

export default function YourComponent() {
  const classes = useStyles();
  return <AppBar className={clsx(classes.header)}></AppBar>;
}

// 样式文件
import { makeStyles } from '@mui/styles';

export const useStyles = makeStyles((theme) => ({
  header: {
    [theme.breakpoints.down('md')]: {
      padding: `0 ${theme.spacing(4)}px`,
    },
  },
}));

额外说明(针对Material-UI v5)

如果使用MUI v5,makeStyles已被标记为废弃,官方推荐使用styled组件或sx prop。若坚持使用makeStyles,需先安装对应依赖:

npm install @mui/styles
# 或
yarn add @mui/styles

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:32:37