如何为你的 React Web 应用添加暗黑模式 先决条件 设置 有趣的部分 摘要 附加内容

2025-05-28

如何为你的 React Web 应用添加暗黑模式

先决条件

设置

有趣的部分

概括

附加功能

我们正处于一个万物皆暗黑模式的时代。如今,大多数应用程序都在导航栏或设置界面附近提供了一个开关,只需点击一下,屏幕就会变暗。有些应用程序甚至默认设置了暗黑模式,例如Mixer
截图 2019-08-15 下午 3.19.23.png,甚至 Netflix 也默认设置了暗黑模式。

使用暗模式确实有助于减少由亮模式引起的眼睛疲劳,在本文结束时,您应该能够在几分钟内将暗模式添加到您的 Reactjs 应用程序中。

先决条件

您应该对以下内容有基本的了解:

  • React 概念(生命周期)
  • CSS 概念,尤其是 CSS 变量
  • Javascript 文档对象模型

设置

创建一个新目录来存放我们的 React 应用程序。

$ mkdir simple_dark_theme_react_app && cd simple_dark_theme_react_app
Enter fullscreen mode Exit fullscreen mode

接下来,我们需要create-react-appCLI,它可以帮助我们在零 webpack 配置的情况下更快地设置一个简单的 React 应用程序。

$ npx create-react-app .
Enter fullscreen mode Exit fullscreen mode

运行我们的应用程序

$ yarn start or npm start
Enter fullscreen mode Exit fullscreen mode

它应该自动启动您的浏览器,如果没有,请访问http://localhost:3000

如果你碰巧遇到了一个fsevents is not a constructor关于它的问题,请访问这个 Github链接

如果这没有帮助,我所做的就是删除lock文件和node_module文件夹并重新安装软件包。

{
  "name": "simple_dark_theme_react_app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.9.0",
    "react-dom": "^16.9.0",
    "react-scripts": "3.1.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

上面是我的 package.json 文件。

有趣的部分

我不会创建一个完整的 React 应用程序,因为这会使这篇博客很长,而且我希望您能够自由发挥创造力,而不会感到困惑。我将使用默认create-react-app模板。

截图 2019-08-15 下午 3.54.58.png

我们将做什么

我们将使用上述默认 React 应用背景颜色作为深色主题,白色作为浅色主题。页面下方会有一个开关,用于切换主题。

注意:我不会使用react钩子,因为我没有时间去研究它,而且类组件对我来说确实有用。

CSS 部分

在切换主题时,CSS 起着至关重要的作用。启动您常用的编辑器,打开src/App.css我们需要添加一些变量的文件。

/* Define our color variables */

html {
  --primary-color: #fff;
  --secondary-color: #282c34;
}

/* Redefine our color variables if the data-theme attr
  value is "dark
*/

html[data-theme="dark"] {
  --primary-color: #282c34;
  --secondary-color: #fff;
}

.App {
  text-align: center;
}

.App-logo {
  animation: App-logo-spin infinite 20s linear;
  height: 40vmin;
  pointer-events: none;
}

.App-header {
  background-color: var(--secondary-color);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: var(--primary-color);
}


@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}
Enter fullscreen mode Exit fullscreen mode

接下来,我们将添加主题切换开关。打开src/App.js文件。

import React from "react";
import logo from "./logo.svg";
import "./App.css";

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <label class="switch">
            <input type="checkbox" />
            <span class="slider round" />
          </label>
        </header>
      </div>
    );
  }
}

export default App;
Enter fullscreen mode Exit fullscreen mode

请注意,我在文件中使用了一个类组件src/App.js

我们需要添加一些 CSS 来设置切换按钮和打开src/App.css文件的样式。

/* CSS styling for our switch */
/* This switch was styled with the help of w3schools */
/* https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_switch */
.switch {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 34px;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  -webkit-transition: .4s;
  transition: .4s;
}

.slider:before {
  position: absolute;
  content: "";
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}

input:checked+.slider {
  background-color: #2196F3;
}

input:focus+.slider {
  box-shadow: 0 0 1px #2196F3;
}

input:checked+.slider:before {
  -webkit-transform: translateX(26px);
  -ms-transform: translateX(26px);
  transform: translateX(26px);
}

/* Rounded sliders */
.slider.round {
  border-radius: 34px;
}

.slider.round:before {
  border-radius: 50%;
}
Enter fullscreen mode Exit fullscreen mode

您应该看到类似下图的内容。
截图 2019-08-15 下午 4.42.41.png

Javascript/React 部分

注意:为了防止在刷新应用程序时丢失状态,我们将主题状态存储在浏览器的中localStorage

打开你的src/App.js文件,让我们更新它,以便我们可以在主题之间切换

import React from "react";
import logo from "./logo.svg";
import "./App.css";

class App extends React.Component {
  // Define a state object to hold our app's state
  state = {
    // Boolean attribute that will allow us to toggle the switch
    // Keep the switch on if the theme is dark
    checked: localStorage.getItem("theme") === "dark" ? true : false,
    /**
     * When a user activates the dark theme we will store the value
     * on localstorage or set default value to light if it is neither dark
     * nor light
     */
    theme: localStorage.getItem("theme")
  };

  componentDidMount() {
    // Update the data-theme attribute of our html tag
    document
      .getElementsByTagName("HTML")[0]
      .setAttribute("data-theme", localStorage.getItem("theme"));
  }

  // Class method allowing us to toggle the theme change
  toggleThemeChange = () => {
    const { checked } = this.state;
    // If theme is light then change to dark
    if (checked === false) {
      // Update localstorage
      localStorage.setItem("theme", "dark");
      /**
       * The document.getElementsByTagName(...).setAttribute(...)
       * will only update the value
       */
      // Update the data-theme attribute of our html tag
      document
        .getElementsByTagName("HTML")[0]
        .setAttribute("data-theme", localStorage.getItem("theme"));
      // Update our state
      this.setState({
        // Ensure our switch is on if we change to dark theme
        checked: true
      });
    } else {
      // Update localstorage
      localStorage.setItem("theme", "light");
      /**
       * The document.getElementsByTagName(...).setAttribute(...)
       * will only update the value until the App is mounted and we change
       * the state of the switch so we will need to introduce
       * a React lifecycle called ˝componentDidMount()˝
       */
      // Update the data-theme attribute of our html tag
      document
        .getElementsByTagName("HTML")[0]
        .setAttribute("data-theme", localStorage.getItem("theme"));
      // Update our state
      this.setState({
        // Ensure our switch is off if we change to light theme
        checked: false
      });
    }
  };

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>Click the switch to toggle themes</p>
          <label class="switch">
            {/* checked attribute is used to determine the state of 
              checkbox
              ----------------------------------------------
              The onChange attribute will toggle our theme change
            */}
            <input
              type="checkbox"
              // checked={this.state.checked}
              defaultChecked={this.state.checked}
              onChange={() => this.toggleThemeChange()}
            />
            <span class="slider round" />
          </label>
        </header>
      </div>
    );
  }
}

export default App;

Enter fullscreen mode Exit fullscreen mode

哇啊!你的应用有暗黑模式了。
darkthemeblog.gif

概括

在这篇博客中,我们能够为我们的反应应用程序添加暗模式。

附加功能

Hooks 版本

https://gist.github.com/Oxyrus/b4edab0372b3c9b1c1b60a59e7955121

文章来源:https://dev.to/wchr/how-to-add-a-dark-mode-to-your-react-web-app-4f1
PREV
图表是终极工程工具
NEXT
🥇首个让你可视化 React/NodeJS 应用的框架 🤯 奖品可视化,名字叫 Wasp Studio 这是派对恶作剧吗!? 一张图片胜过千言万语 帮助计算机帮助我们