React 웹 앱에 다크 모드를 추가하는 방법

우리는 현재 모든 시대에 다크 모드에 살고 있습니다. 오늘날 대부분의 앱에는 탐색 표시줄 또는 설정 주변 어딘가에 스위치가 있어 클릭하기만 하면 화면이 어두워집니다. 일부 앱은 기본적으로 어두운 모드로 제공됩니다(예: Mixer).
, Netflix에도 기본적으로 어두운 모드가 있습니다.

어두운 모드를 사용하면 밝은 모드로 인한 눈의 피로를 줄이는 데 정말 도움이 되며 이 기사가 끝날 때까지 몇 분 안에 Reactjs 앱에 어두운 모드를 추가할 수 있을 것입니다.

전제 조건



다음에 대한 기본적인 이해가 있어야 합니다.
  • 반응 개념(라이프 사이클)
  • CSS 개념, 특히 CSS 변수
  • Javascript 문서 개체 모델

  • 설정



    React 앱을 보관할 새 디렉토리를 만듭니다.

    $ mkdir simple_dark_theme_react_app && cd simple_dark_theme_react_app
    

    다음으로 웹팩 구성 없이 간단한 React 앱을 더 빠르게 설정하는 데 도움이 되는 create-react-app CLI가 필요합니다.

    $ npx create-react-app .
    

    앱 실행

    $ yarn start or npm start
    
    http://localhost:3000을 방문하지 않으면 브라우저가 자동으로 실행됩니다.

    If you happen to face a fsevents is not a constructor visit this Github issues raised about it link

    If that does not help, all I did was delete the lock file and the node_module folder and reinstalled the packages.



    {
      "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"
        ]
      }
    }
    

    위는 내 package.json 파일입니다.

    재미있는 부분



    전체 반응 애플리케이션을 만들지는 않겠습니다. 왜냐하면 이 블로그가 상당히 길어질 수 있고 혼란 없이 창의적이기를 바랍니다. 기본 create-react-app 템플릿으로 작업하겠습니다.


    우리가 할 일



    우리가 할 일은 위의 기본 React 앱 배경색을 어두운 테마로 사용하고 흰색을 밝은 테마로 사용하는 것입니다. 테마 변경을 전환할 수 있도록 페이지 아래에 스위치가 있습니다.

    Note: I will not use react hooks because I haven't had the time to look into that and also class components really work for me.


    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);
      }
    }
    

    다음으로 테마 토글 스위치를 추가합니다. 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;
    

    Note that I am using a class component in the src/App.js file.



    토글 버튼의 ​​스타일을 지정하려면 몇 가지 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%;
    }
    

    아래 이미지와 비슷한 것이 있어야 합니다.

    자바스크립트/반응 파트



    Note: In order to prevent losing state when refreshing the app, we will store the theme state in our browser 's 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;
    
    

    왈라아아! 앱에 어두운 모드가 있습니다.

    요약



    이 블로그에서 반응 앱에 다크 모드를 추가할 수 있었습니다.

    엑스트라


  • 레포 link
  • 코드샌드박스 link
  • 데모 link

  • 후크 버전



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


    .ltag__user__id__50675 .follow-action-button {
    배경색: #8001b7 !중요;
    색상: #e1e1e1 !중요;
    테두리 색상: #8001b7 !중요;
    }



    안드레스 페레즈



    Web developer from 🇨🇴

    좋은 웹페이지 즐겨찾기