如何修复页面刷新时主题切换的闪烁问题?(Mantine v7.1.2 - NextJS)
解决Mantine v7.1.2 + NextJS页面刷新时深色主题闪烁问题
核心原因
服务端渲染阶段无法读取浏览器localStorage中保存的用户颜色偏好,导致初始渲染使用你设置的light默认主题,但客户端加载后读取本地存储切换到深色主题,两者样式不匹配引发闪烁。
解决步骤
1. 实现颜色方案持久化同步
在_app.tsx中结合ColorSchemeProvider和useEffect,确保客户端加载后才读取本地存储的颜色偏好,避免服务端与客户端渲染冲突:
import { useState, useEffect } from 'react'; import { MantineProvider, ColorSchemeProvider, ColorScheme } from '@mantine/core'; import { defaultTheme } from '../your-theme-path'; // 替换为你的主题文件路径 export default function App({ Component, pageProps }) { // 初始值设为默认light,保证服务端渲染一致性 const [colorScheme, setColorScheme] = useState<ColorScheme>('light'); // 切换颜色方案的逻辑 const toggleColorScheme = (value?: ColorScheme) => { setColorScheme(value || (colorScheme === 'dark' ? 'light' : 'dark')); }; // 客户端加载后读取本地存储的颜色偏好 useEffect(() => { const savedScheme = localStorage.getItem('mantine-color-scheme') as ColorScheme; if (savedScheme) setColorScheme(savedScheme); }, []); // 颜色方案变更时保存到本地存储 useEffect(() => { localStorage.setItem('mantine-color-scheme', colorScheme); }, [colorScheme]); return ( <ColorSchemeProvider colorScheme={colorScheme} toggleColorScheme={toggleColorScheme}> <MantineProvider theme={defaultTheme} defaultColorScheme={colorScheme}> <Component {...pageProps} /> </MantineProvider> </ColorSchemeProvider> ); }
2. 提前注入初始主题样式(Pages Router)
在_document.tsx中添加初始颜色方案的样式,让首屏直接加载对应主题样式,避免切换闪烁:
import { Html, Head, Main, NextScript } from 'next/document'; import { getColorSchemeStyles } from '@mantine/core'; export default function Document() { return ( <Html> <Head> {/* 注入light主题的初始样式,与服务端渲染保持一致 */} <style dangerouslySetInnerHTML={{ __html: getColorSchemeStyles('light') }} /> </Head> <body> <Main /> <NextScript /> </body> </Html> ); }
如果使用App Router(NextJS 13+),将上述样式注入逻辑放到app/layout.tsx的<head>标签内即可。
3. 引入StyleReset确保样式一致性
在MantineProvider内部添加StyleReset,清除浏览器默认样式,避免主题切换时的额外样式冲突:
import { StyleReset } from '@mantine/core'; // 在MantineProvider内部添加 <MantineProvider theme={defaultTheme} defaultColorScheme={colorScheme}> <StyleReset /> <Component {...pageProps} /> </MantineProvider>
关键注意事项
- 绝对不要在服务端代码中直接访问
localStorage,只能在客户端useEffect中读取 - 确保
defaultColorScheme与colorScheme状态值保持一致,避免服务端与客户端渲染样式不匹配 - 如果用户未手动切换过主题,会始终使用默认的
light主题,不会出现闪烁
内容的提问来源于stack exchange,提问作者AnonymousBlank
相关产品推荐
相关产品推荐

