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

Next.js集成Material UI后刷新样式丢失,已配置_app、_document仍未解决

解决Next.js + Material UI 页面刷新样式丢失方案

以下方案针对你当前使用的Material UI v4(包名为@material-ui/core)场景适配:

1. 补全_app.tsx缺失的核心配置

你现有配置只添加了服务端样式清理逻辑,缺少统一的样式实例、主题配置,会导致服务端和客户端生成的CSS类名不一致,hydrate完成后样式失效。补全后的完整_app.tsx参考:

import { useEffect } from 'react'
import { ThemeProvider, createTheme } from '@material-ui/core/styles'
import { StylesProvider, jssPreset } from '@material-ui/styles'
import { create } from 'jss'

// 全局创建唯一的jss实例,统一类名生成规则
const jss = create({
  plugins: [...jssPreset().plugins],
  insertionPoint: typeof document !== 'undefined' ? document.head : undefined,
})
// 全局创建唯一的theme实例,不要在组件内部动态创建
const theme = createTheme({
  // 此处填写你的自定义主题配置
})

export default function MyApp({ Component, pageProps }) {
  useEffect(() => {
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles) {
      jssStyles.parentElement.removeChild(jssStyles);
    }
  }, []);

  return (
    <StylesProvider jss={jss}>
      <ThemeProvider theme={theme}>
        <Component {...pageProps} />
      </ThemeProvider>
    </StylesProvider>
  )
}

2. 优化_document.tsx配置

你当前的_document.tsx基本正确,补充服务端样式的id标识,确保和_app.tsx中的清理逻辑匹配即可:

import React from 'react';
import { ServerStyleSheets } from '@material-ui/core/styles';
import Document, { Head, Html, Main, NextScript } from 'next/document';
export default class MyDocument extends Document {

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

MyDocument.getInitialProps = async (ctx) => {
  const sheets = new ServerStyleSheets();
  const originalRenderPage = ctx.renderPage;
  ctx.renderPage = () => {
    return originalRenderPage({
      enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
    });
  };
  const initialProps = await Document.getInitialProps(ctx);
  return {
    ...initialProps,
    styles: [
      // 给MUI服务端样式添加指定id,优先于Next.js默认样式注入
      sheets.getStyleElement({ id: 'jss-server-side' }),
      ...React.Children.toArray(initialProps.styles),
    ],
  };
};

3. 其他冲突场景排查

  • 如果你同时使用了styled-components、emotion等其他CSS-in-JS库,需要单独配置对应库的服务端渲染逻辑,避免样式注入顺序冲突
  • 不要在组件内部动态生成theme实例,每次渲染生成新的theme会触发MUI全量重新生成类名,导致样式丢失
  • 配置修改完成后删除项目.next缓存目录,重新启动开发服务验证效果
  • 如果你升级到了Material UI v5(包名@mui/material),需要完全卸载旧的@material-ui相关依赖,改用v5官方提供的emotion相关服务端渲染配置,当前v4的ServerStyleSheets配置在v5中不生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:00:04