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
相关产品推荐
相关产品推荐

