React+Styled-Components暗黑模式实践

· 532 words · 2 minute read

在React项目中,使用styled-components完成暗黑模式的切换

暗黑模式切换 🔗

先看效果吧👀👀

darkmode.gif

使用styled-components 🔗

安装styled-components 🔗

pnpm i styled-components

react项目中引入全局暗黑模式css 🔗

创建一个全局的GlobalStyle.js文件用来放置css变量,需要使用styled-components中的 createGlobalStyle 来创建css,你可以创建更多css颜色变量

import { createGlobalStyle } from "styled-components";

const GlobalStyles = createGlobalStyle`
:root {
  &, &.light-mode {
  /* Grey */
  --color-grey-0: #fff;
  --color-grey-50: #f9fafb;
  --color-grey-100: #f3f4f6;
  --color-grey-200: #e5e7eb;
  }
  
  &.dark-mode {
    --color-grey-0: #18212f;
--color-grey-50: #111827;
--color-grey-100: #1f2937;
--color-grey-200: #374151;
  }
  
}

*,
*::before,
*::after {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}
`;

export default GlobalStyles;

在App.js中作为组件使用

import GlobalStyles from "./styles/GlobalStyles";
function App() {
  return (
    <>
      <GlobalStyles />
      <Layout />
    </>
  );
}

使用context创建DarkModeProvide 🔗

import { createContext, useContext, useEffect } from "react";
import { useLocalStorageState } from "../hooks/useLocalStorageState";

const DarkModeContext = createContext();

function DarkModeProvider({ children }) {
  const [isDarkMode, setIsDarkMode] = useLocalStorageState(
    window.matchMedia("(prefers-color-scheme: dark)").matches,
    "isDarkMode"
  );

  useEffect(() => {
    if (isDarkMode) {
      document.documentElement.classList.add("dark-mode");
      document.documentElement.classList.remove("light-mode");
    } else {
      document.documentElement.classList.add("light-mode");
      document.documentElement.classList.add("dark-mode");
    }
  }, [isDarkMode]);

  function toggleDarkMode() {
    setIsDarkMode((isDark) => !isDark);
  }

  return (
    <DarkModeContext.Provider value={{ isDarkMode, toggleDarkMode }}>
      {children}
    </DarkModeContext.Provider>
  );
}

function useDarkMode() {
  const context = useContext(DarkModeContext);
  if (context === undefined)
    throw new Error("DarkModeContext was used outside of DarkModeProvider");
  return context;
}

export { DarkModeProvider, useDarkMode };

在App中使用,包裹styled-components创建的全局样式组件

function App() {
  return (
    <DarkModeProvider>
      <GlobalStyles />
      <Layout />
    </DarkModeProvider>
  );
}

切换暗黑模式 🔗

创建一个组件用于切换暗黑模式, DarkMode.jsx

export default function DarkMode() {
  const { isDarkMode, toggleDarkMode } = useDarkMode();
  return (
    <DarkDiv onClick={toggleDarkMode}>
      {isDarkMode ? (
        <HiOutlineSun size="1.5rem" color="white" />
      ) : (
        <HiOutlineMoon size="1.5rem" />
      )}
    </DarkDiv>
  );
}

至此,切换暗黑模式的功能就完成了~~~😋😜