Next.js Dark Theme -当页面重新加载时,无法阻止页面返回到Light模式

5anewei6  于 2023-11-18  发布在  其他
关注(0)|答案(1)|浏览(95)

我在我的next.js应用程序中的主题挂钩有问题。重新加载页面时,黑暗主题在恢复到光明主题之前有一个初始 Flink 效果。localStorgae表明重新加载黑暗主题在恢复到光明主题之前启动。
到目前为止,我所尝试的:
1.如UseTheme.tsx代码片段所示,在完全加载页面之前,我尝试为主题添加一个事件侦听器,但没有成功。
1.在_document.tsx中,我试图保存从黑暗到光明的主题变化,反之亦然:

if (theme === 'dark') {
                document.documentElement.classList.add('dark');
                document.documentElement.classList.remove('light');
              } else {
                document.documentElement.classList.remove('dark');
                document.documentElement.classList.add('light');
              }
            }

字符串
这应该允许跟踪主题,并在主题钩子中对最后一个useEffect进行相同的更改,但这不起作用。

编辑:

我参考了tailwind文档,并对_document.tsx进行了更改。此外,主题主题有一些错误,例如preferDarkQuery作为 prop 类型,已被删除并修改了代码。这应该可以工作,但我仍然有同样的问题,我不确定如何解决它。

主题.tsx:

import React, { useEffect, useState } from 'react';

const UseTheme = () => {
  
  const darkQuery = '(prefers-color-scheme: dark)';
  const [mode, setMode] = useState('');

  useEffect(() => {
    const mediaQuery = window.matchMedia(darkQuery);
    const userPref = window.localStorage.getItem('theme');

    const handleChange = () => {
      if (userPref) {
        const newMode = userPref === 'dark' ? 'dark' : 'light';
        setMode(newMode);
        if (newMode === 'dark') {
          document.documentElement.classList.add('dark');
        } else {
          document.documentElement.classList.remove('dark');
        }
      } else {
        let newMode = mediaQuery.matches ? 'dark' : 'light';
        setMode(newMode);
        window.localStorage.setItem('theme', newMode)
        if (newMode === 'dark') {
          document.documentElement.classList.add('dark');
        } else {
          document.documentElement.classList.remove('dark');
        }
      }
    }
    handleChange();

    mediaQuery.addEventListener('change', handleChange);

    return () => 
      mediaQuery.removeEventListener('change', handleChange);
    
  }, []);

  useEffect(() => {
    if (mode === 'dark') {
      window.localStorage.setItem('theme', 'dark');
      document.documentElement.classList.add('dark');
    } else {
      window.localStorage.setItem('theme', 'light');
      document.documentElement.classList.remove('dark');
    }
  }, [mode]);

  return {mode, setMode};
};

export default UseTheme;

_document.tsx:

import { Html, Head, Main, NextScript } from 'next/document';
import Script from 'next/script';

export default function Document() {

  return (
    <Html lang="en">
      <Head />
      <body>
        <Script id="use-theme" strategy="beforeInteractive">
          {`
          if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
            document.documentElement.classList.add('dark')
          } else {
            document.documentElement.classList.remove('dark')
          }
          `}
        </Script>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

pdtvr36n

pdtvr36n1#

要解决重新加载页面时Next.js应用中的 Flink 问题,并确保深色和浅色主题之间的平滑过渡,请考虑在根布局的HTML标记中包含以下属性:
第一个月

相关问题