1

使用 React hooks 监听系统的暗黑模式

 2 years ago
source link: https://www.fly63.com/article/detial/11130
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

苹果的“暗黑模式”带来了全然一新的外观,它能使您的眼睛放松,并有助于您专心工作。暗黑模式使用一种较深的配色方案,这种配色作用于整个系统,现在大部分网站也加入了暗黑模式,包括 Tailwindcss、antd design 等都支持了暗黑模式,因此我们的网站也要适配系统皮肤。

6205b667ccb7e.jpg

css 实现

暗模式传统上是通过使用 prefers-color-scheme 媒体查询来实现的,当暗黑模式被激活时,它可以重新应用一套样式。

body {
  color: black;
  background: white;
}
@media (prefers-color-scheme: dark) {
  body {
    color: white;
    background: black;
  }
}

react hooks 实现

前端页面中除了使用 css 实现外,还有很大部分是使用 JavaScript 实现的,比如 echarts 图表等,这时就需要使用 JavaScript, 可以使用window.matchMedia[1] 来获取皮肤颜色。我们可以把这个逻辑写成一个自定义 hooks

import { useEffect, useState } from "react"

export type ThemeName = "light" | "dark"

function useTheme() {
  const [themeName, setThemeName] = useState<ThemeName>("light")
  useEffect(() => {
    // 设置初始皮肤
    if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
      setThemeName("dark")
    } else {
      setThemeName("light")
    }
    // 监听系统颜色切换
    window
      .matchMedia("(prefers-color-scheme: dark)")
      .addEventListener("change", (event) => {
        if (event.matches) {
          setThemeName("dark")
        } else {
          setThemeName("light")
        }
      })
  }, [])
  return {
    themeName,
    isDarkMode: themeName === "dark",
    isLightMode: themeName === "light",
  }
}

export default useTheme

下面代码是配合 echarts 使用

import './styles.css'
import React, { useRef, useEffect } from 'react'
import * as echarts from 'echarts'
import useTheme from './hooks/useTheme'

export default function App() {
  const domRef = useRef(null)
  const { isDarkMode } = useTheme()
  useEffect(() => {
    var myChart = echarts.init(domRef.current, isDarkMode ? 'dark' : 'light')
    var option = {
      xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
      },
      yAxis: {
        type: 'value',
      },
      series: [
        {
          data: [820, 932, 901, 934, 1290, 1330, 1320],
          type: 'line',
          smooth: true,
        },
      ],
    }

    myChart.setOption(option)
    return () => {
      myChart.dispose()
    }
  }, [isDarkMode])
  return (
    <div className='App'>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <div ref={domRef} style={{ height: 500 }}></div>
    </div>
  )
}

链接: https://www.fly63.com/article/detial/11130


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK