React 웹 앱에 다크 모드를 추가하는 방법
, Netflix에도 기본적으로 어두운 모드가 있습니다.
어두운 모드를 사용하면 밝은 모드로 인한 눈의 피로를 줄이는 데 정말 도움이 되며 이 기사가 끝날 때까지 몇 분 안에 Reactjs 앱에 어두운 모드를 추가할 수 있을 것입니다.
전제 조건
다음에 대한 기본적인 이해가 있어야 합니다.
설정
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;
왈라아아! 앱에 어두운 모드가 있습니다.
요약
이 블로그에서 반응 앱에 다크 모드를 추가할 수 있었습니다.
엑스트라
$ mkdir simple_dark_theme_react_app && cd simple_dark_theme_react_app
$ npx create-react-app .
$ yarn start or npm start
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"
]
}
}
전체 반응 애플리케이션을 만들지는 않겠습니다. 왜냐하면 이 블로그가 상당히 길어질 수 있고 혼란 없이 창의적이기를 바랍니다. 기본
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;
왈라아아! 앱에 어두운 모드가 있습니다.
요약
이 블로그에서 반응 앱에 다크 모드를 추가할 수 있었습니다.
엑스트라
후크 버전
https://gist.github.com/Oxyrus/b4edab0372b3c9b1c1b60a59e7955121 의해
.ltag__user__id__50675 .follow-action-button {
배경색: #8001b7 !중요;
색상: #e1e1e1 !중요;
테두리 색상: #8001b7 !중요;
}
안드레스 페레즈
Web developer from 🇨🇴
Reference
이 문제에 관하여(React 웹 앱에 다크 모드를 추가하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/wchr/how-to-add-a-dark-mode-to-your-react-web-app-4f1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)