簡體   English   中英

Gatsby 暗模式切換在 Safari 的主頁上不起作用

[英]Gatsby dark mode toggle not working on homepage in Safari

我剛剛在我的 Gatsby 網站中集成一個明暗模式切換。 我基於Josh Comeau 的文章,它在 Chrome 中運行良好。 但是在主頁上使用 Safari 時,當我單擊切換按鈕時,除非我調整 window 的大小,否則背景顏色不會改變。 這是我的gatsby-ssr.js

import React from 'react';

import { THEME_COLORS } from 'utils/theme-colors';

import { LOCAL_STORAGE_THEME_KEY } from './src/contexts/ThemeContext';

const SetTheme = () => {
  let SetThemeScript = `
    (function() {
      function getInitialTheme() {
        const persistedColorPreference = window.localStorage.getItem('${LOCAL_STORAGE_THEME_KEY}');
        const hasPersistedPreference = typeof persistedColorPreference === 'string';
 
        if (hasPersistedPreference) {
            return persistedColorPreference;
        }
        
        const mql = window.matchMedia('(prefers-color-scheme: dark)');
        const hasMediaQueryPreference = typeof mql.matches === 'boolean';
        
        if (hasMediaQueryPreference) {
            return mql.matches ? 'dark' : 'light';
        }
        return 'light';
      }

      const colorMode = getInitialTheme();
      const root = document.documentElement;
      root.style.setProperty(
        '--color-primary',
        colorMode === 'dark'
          ? '${THEME_COLORS.dark}'
          : '${THEME_COLORS.light}'
      );
      root.style.setProperty(
        '--color-secondary',
        colorMode === 'dark'
          ? '${THEME_COLORS.light}'
          : '${THEME_COLORS.dark}'
      );
      root.style.setProperty(
        '--color-accent',
        colorMode === 'dark'
          ? '${THEME_COLORS.accentLight}'
          : '${THEME_COLORS.accentDark}'
      );
      root.style.setProperty('--initial-color-mode', colorMode);
    })()`;
  return <script id="theme-hydration" dangerouslySetInnerHTML={{ __html: SetThemeScript }} />;
};
export const onRenderBody = ({ setPreBodyComponents }) => {
  setPreBodyComponents(<SetTheme />);
};

和我的ThemeToggle組件:

import React, { useContext } from 'react';

import { ThemeContext } from 'contexts/ThemeContext';
import { DarkModeSwitch } from 'react-toggle-dark-mode';
import { THEME_COLORS } from 'utils/theme-colors';

import s from './ThemeToggle.scss';

export const ThemeToggle = () => {
  const { theme, toggleTheme } = useContext(ThemeContext);

  const toggleDarkMode = (checked: boolean) => {
    toggleTheme(checked ? 'dark' : 'light');
  };

  return (
    <div className={s.toggler}>
      <DarkModeSwitch
        checked={theme === 'dark'}
        onChange={toggleDarkMode}
        size={20}
        sunColor={THEME_COLORS.dark}
        moonColor={THEME_COLORS.light}
      />
    </div>
  );
};

有想法該怎么解決這個嗎?

ThemeContext值解構的toggleTheme屬性似乎不會觸發重新渲染,但調整瀏覽器 window 的大小會觸發。 Josh 通過提供一個帶有副作用的設置器 function 來處理這個問題(它直接操作根 styles):

  const contextValue = React.useMemo(() => {
    function setColorMode(newValue) {
      const root = window.document.documentElement;

      localStorage.setItem(COLOR_MODE_KEY, newValue);

      Object.entries(COLORS).forEach(([name, colorByTheme]) => {
        const cssVarName = `--color-${name}`;

        root.style.setProperty(cssVarName, colorByTheme[newValue]);
      });

      rawSetColorMode(newValue);
    }

    return {
      colorMode,
      setColorMode,
    };
  }, [colorMode, rawSetColorMode]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM