繁体   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