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

如何修复页面刷新时主题切换的闪烁问题?(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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:02:36