การนำ Dark Mode ไปใช้ใน React Apps โดยใช้ styled-components
เผยแพร่แล้ว: 2022-03-10หนึ่งในคุณสมบัติซอฟต์แวร์ที่ร้องขอบ่อยที่สุดคือโหมดมืด (หรือโหมดกลางคืนตามที่คนอื่นเรียก) เราเห็นโหมดมืดในแอพที่เราใช้ทุกวัน โหมดมืดกลายเป็นส่วนสำคัญสำหรับบริษัทที่ต้องการดูแลสายตาของผู้ใช้ตั้งแต่มือถือไปจนถึงเว็บแอป
โหมดมืดเป็นคุณสมบัติเสริมที่แสดงพื้นผิวที่มืดเป็นส่วนใหญ่ใน UI บริษัทใหญ่ๆ ส่วนใหญ่ (เช่น YouTube, Twitter และ Netflix) ได้นำโหมดมืดมาใช้ในแอพมือถือและเว็บ
แม้ว่าเราจะไม่เจาะลึกถึง React และ styled-components แต่ความรู้พื้นฐานเกี่ยวกับ React, CSS และ styled-components จะมีประโยชน์ กวดวิชานี้จะเป็นประโยชน์กับผู้ที่ต้องการปรับปรุงเว็บแอปพลิเคชันของตนโดยจัดไว้สำหรับผู้ที่รักโหมดมืด
ไม่กี่วันก่อนเขียนบทความนี้ StackOverflow ได้ประกาศเปิดตัวโหมดมืด ให้ผู้ใช้มีโอกาสสลับไปมาระหว่างสองโหมด
โหมดมืดช่วยลดอาการปวดตาและช่วยให้คุณทำงานบนคอมพิวเตอร์หรือโทรศัพท์มือถือเป็นเวลานาน
โหมดมืดคืออะไร?
โหมดมืดคือชุดสีของอินเทอร์เฟซใดๆ ที่แสดงข้อความและองค์ประกอบอินเทอร์เฟซบนพื้นหลังสีเข้ม ซึ่งทำให้หน้าจอดูโทรศัพท์มือถือ แท็บเล็ต และคอมพิวเตอร์ง่ายขึ้นเล็กน้อย โหมดมืดช่วยลดแสงที่ปล่อยออกมาจากหน้าจอ ในขณะที่ยังคงอัตราส่วนคอนทราสต์สีขั้นต่ำที่จำเป็นสำหรับการอ่านได้
ทำไมคุณควรสนใจโหมดมืด?
โหมดมืดปรับปรุงการยศาสตร์ของภาพโดยลดอาการปวดตา ปรับหน้าจอให้เข้ากับสภาพแสงในปัจจุบัน และให้ความสะดวกในการใช้งานในเวลากลางคืนหรือในสภาพแวดล้อมที่มืด
ก่อนใช้งานโหมดมืดในแอปของเรา มาดูประโยชน์ของมันกันก่อน
ประหยัดพลังงาน
โหมดมืดในเว็บและแอปบนอุปกรณ์เคลื่อนที่สามารถยืดอายุแบตเตอรี่ของอุปกรณ์ได้ Google ได้ยืนยันว่าโหมดมืดบนหน้าจอ OLED นั้นช่วยยืดอายุแบตเตอรี่ได้อย่างมาก
ตัวอย่างเช่น ที่ความสว่าง 50% โหมดมืดในแอป YouTube จะประหยัดพลังงานหน้าจอมากกว่าพื้นหลังสีขาวเรียบประมาณ 15% ที่ความสว่างหน้าจอ 100% อินเทอร์เฟซมืดช่วยประหยัดพลังงานหน้าจอได้มากถึง 60%
โหมดมืดสวยงาม
โหมดมืดนั้นสวยงามและสามารถเพิ่มความน่าดึงดูดของหน้าจอได้อย่างมาก
แม้ว่าผลิตภัณฑ์ส่วนใหญ่จะมีสีขาวนวลที่ดูคล้ายคลึงกัน แต่โหมดมืดก็มีบางสิ่งที่แตกต่างออกไปซึ่งให้ความรู้สึกลึกลับและแปลกใหม่
นอกจากนี้ยังให้โอกาสที่ดีในการนำเสนอเนื้อหากราฟิก เช่น แดชบอร์ด รูปภาพ และภาพถ่ายในรูปแบบใหม่
เมื่อคุณรู้แล้วว่าเหตุใดคุณจึงควรใช้โหมดมืดในเว็บแอปถัดไป มาเจาะลึกเข้าไปในองค์ประกอบที่มีสไตล์ ซึ่งเป็นทรัพยากรที่กำหนดของบทช่วยสอนนี้
โหมดมืดคือชุดสีของอินเทอร์เฟซที่แสดงข้อความและองค์ประกอบอินเทอร์เฟซบนพื้นหลังสีเข้ม ซึ่งทำให้ดูบนโทรศัพท์มือถือ แท็บเล็ต และคอมพิวเตอร์ได้ง่ายขึ้นเล็กน้อย
“
อะไรคือองค์ประกอบที่มีสไตล์?
ตลอดบทความนี้ เราจะใช้ไลบรารีที่มีสไตล์องค์ประกอบบ่อยมาก มีหลายวิธีในการจัดรูปแบบเว็บแอปที่ทันสมัยอยู่เสมอ มีวิธีการจัดรูปแบบแบบดั้งเดิมในระดับเอกสาร ซึ่งรวมถึงการสร้างไฟล์ index.css
และเชื่อมโยงไปยัง HTML หรือการจัดรูปแบบภายในไฟล์ HTML
มีการเปลี่ยนแปลงมากมายในวิธีการจัดรูปแบบเว็บแอปเมื่อเร็วๆ นี้ นับตั้งแต่เปิดตัว CSS-in-JS
CSS-in-JS หมายถึงรูปแบบที่ CSS ประกอบขึ้นโดยใช้ JavaScript ใช้เทมเพลตที่ติดแท็กเพื่อจัดรูปแบบองค์ประกอบในไฟล์ JavaScript
หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ CSS-in-JS โปรดดูบทความของ Anna Monus ในหัวข้อนี้
styled-components คือไลบรารี CSS-in-JS ที่ให้คุณใช้ฟีเจอร์ทั้งหมดของ CSS ที่คุณชื่นชอบ รวมถึงคิวรี่สื่อ ตัวเลือกหลอก และการซ้อน
ทำไมต้องเป็นองค์ประกอบที่มีสไตล์?
styled-components ถูกสร้างขึ้นด้วยเหตุผลดังต่อไปนี้:
- ไม่มีชื่อชั้น นรก
แทนที่จะต้องเกาหัวเพื่อค้นหาชื่อคลาสสำหรับองค์ประกอบ styled-components จะสร้างชื่อคลาสเฉพาะสำหรับสไตล์ของคุณ คุณจะไม่ต้องกังวลกับการสะกดผิดหรือใช้ชื่อชั้นเรียนที่ไม่มีความหมาย - การใช้อุปกรณ์ประกอบฉาก
styled-components ช่วยให้เราสามารถขยายคุณสมบัติการจัดสไตล์โดยใช้พารามิเตอร์props
ซึ่งมักใช้ใน React ดังนั้นจึงส่งผลต่อความรู้สึกของส่วนประกอบแบบไดนามิกผ่านสถานะของแอปพลิเคชัน - รองรับไวยากรณ์ Sass
การเขียนไวยากรณ์ Sass นอกกรอบโดยไม่ต้องตั้งค่าตัวประมวลผลล่วงหน้าหรือเครื่องมือสร้างเพิ่มเติมสามารถทำได้ด้วยองค์ประกอบที่มีสไตล์ ในการกำหนดสไตล์ของคุณ คุณสามารถใช้อักขระ&
เพื่อกำหนดเป้าหมายองค์ประกอบปัจจุบัน ใช้ตัวเลือกหลอก และทดลองกับการซ้อน - ธีม
styled-components มีการสนับสนุนชุดรูปแบบที่สมบูรณ์โดยการส่งออกส่วนประกอบ wrapperThemeProvider
ส่วนประกอบนี้จัดเตรียมธีมให้กับส่วนประกอบ React ทั้งหมดภายในตัวมันเองผ่าน Context API ในแผนผังการแสดงผล องค์ประกอบที่มีสไตล์ทั้งหมดจะมีสิทธิ์เข้าถึงธีมที่จัดเตรียมไว้ แม้ว่าจะอยู่ลึกหลายระดับก็ตาม ในขณะที่เราดำเนินการต่อในบทช่วยสอนนี้ เราจะเจาะลึกถึงคุณสมบัติธีมขององค์ประกอบที่มีสไตล์
หากต้องการเรียนรู้ข้อดีเพิ่มเติมของส่วนประกอบที่มีสไตล์ โปรดดูบทความของ Kris Guzman
การใช้โหมดมืด
ในบทความนี้ เราจะใช้โหมดมืดบนหน้าเว็บที่คล้ายกับ YouTube
เพื่อปฏิบัติตาม ตรวจสอบให้แน่ใจว่าคุณโคลนที่เก็บดั้งเดิมจากสาขา starter
การตั้งค่า
มาติดตั้งการพึ่งพาทั้งหมดในไฟล์ package.json
ของเรา จากเทอร์มินัล ให้รันคำสั่งต่อไปนี้:
npm install
เมื่อติดตั้งสำเร็จ ให้รัน npm start
นี่คือลักษณะของหน้าเว็บที่ไม่มีการใช้โหมดมืด
ในการติดตั้ง styled-components
ในเทอร์มินัลของคุณให้รัน npm install styled-components
การดำเนินการ
ในการปรับใช้โหมดมืด เราจำเป็นต้องสร้างองค์ประกอบสี่ส่วนที่แตกต่างกัน
-
Theme
ซึ่งรวมถึงคุณสมบัติสีของธีมสีอ่อนและสีเข้มของเรา -
GlobalStyles
ประกอบด้วยสไตล์สากลสำหรับทั้งเอกสาร -
Toggler
ซึ่งจะเก็บองค์ประกอบปุ่มที่สลับการทำงาน -
useDarkMode
เบ็ดที่กำหนดเองนี้จัดการตรรกะที่อยู่เบื้องหลังการเปลี่ยนธีมและความคงอยู่ของธีมของเราใน localStorage
ส่วนประกอบธีม
ในโฟลเดอร์ src
คุณจะเห็นส่วนประกอบในโฟลเดอร์ components
สร้างไฟล์ Themes.js
และเพิ่มโค้ดต่อไปนี้ลงไป
export const lightTheme = { body: '#FFF', text: '#363537', toggleBorder: '#FFF', background: '#363537', } export const darkTheme = { body: '#363537', text: '#FAFAFA', toggleBorder: '#6B8096', background: '#999', }
ที่นี่ เราได้กำหนดและส่งออกวัตถุ lightTheme
และ darkTheme
ด้วยตัวแปรสีที่แตกต่างกัน อย่าลังเลที่จะทดลองและปรับแต่งตัวแปรให้เหมาะกับคุณ
globalStyles Component
ที่เหลืออยู่ในโฟลเดอร์ components
ของคุณ สร้างไฟล์ globalStyles.js
และเพิ่มรหัสต่อไปนี้:
import { createGlobalStyle} from "styled-components" export const GlobalStyles = createGlobalStyle` body { background: ${({ theme }) => theme.body}; color: ${({ theme }) => theme.text}; font-family: Tahoma, Helvetica, Arial, Roboto, sans-serif; transition: all 0.50s linear; } `
เราได้นำเข้า createGlobalStyle
จากองค์ประกอบที่มีสไตล์ เมธอด createGlobalStyle
แทนที่เมธอด injectGlobal ที่เลิกใช้แล้วจาก styled-components เวอร์ชัน 3 เมธอดนี้จะสร้างคอมโพเนนต์ React ซึ่งเมื่อเพิ่มลงในทรีคอมโพเนนต์ของคุณจะใส่สไตล์โกลบอลลงในเอกสาร ในกรณีของเรา App.js
เรากำหนดองค์ประกอบ GlobalStyle
และกำหนดคุณสมบัติ background
และ color
ให้กับค่าจากวัตถุของธีม ดังนั้น ทุกครั้งที่เราสลับการสลับ ค่าจะเปลี่ยนไปขึ้นอยู่กับธีมสีเข้มหรือวัตถุธีมสีอ่อนที่เราส่งไปยัง ThemeProvider
(ซึ่งจะถูกสร้างขึ้นในภายหลังเมื่อเราดำเนินการต่อไป)
คุณสมบัติการเปลี่ยนแปลง 0.50s
ช่วยให้การเปลี่ยนแปลงนี้เกิดขึ้นได้ราบรื่นขึ้นเล็กน้อย เพื่อที่เมื่อเราสลับไปมา เราจะเห็นการเปลี่ยนแปลงเกิดขึ้น
การสร้างฟังก์ชันการสลับธีม
ในการใช้ฟังก์ชันสลับธีม เราจำเป็นต้องเพิ่มโค้ดเพียงไม่กี่บรรทัด ในไฟล์ App.js
ให้เพิ่มโค้ดต่อไปนี้ (โปรดทราบว่าโค้ดที่ไฮไลต์คือสิ่งที่คุณควรเพิ่ม):
import React, { useState, useEffect } from "react";
import {ThemeProvider} from "styled-components"; import { GlobalStyles } from "./components/Globalstyle"; import { lightTheme, darkTheme } from "./components/Themes"
import "./App.css"; import dummyData from "./data"; import CardList from "./components/CardList"; const App = () => { const [videos, setVideos] = useState([]);
const [theme, setTheme] = useState('light'); const themeToggler = () => { theme === 'light' ? setTheme('dark') : setTheme('light') }
useEffect(() => { const timer = setTimeout(() => { setVideos(dummyData); }, 1000); return () => clearTimeout(timer); }, []); return (
<ThemeProvider theme={theme === 'light' ? lightTheme : darkTheme}> <> <GlobalStyles/>
<div className="App">
<button onClick={themeToggler}>Switch Theme</button>
{ videos.map((list, index) => { return ( <section key={index}> <h2 className="section-title">{list.section}</h2> <CardList list={list} /> <hr /> </section> ); })} </div>
</> </ThemeProvider>
); }; export default App;
โค้ดที่ไฮไลต์คือโค้ดที่เพิ่มใหม่ใน App.js
เราได้นำเข้า ThemeProvider
จาก styled-components
ThemeProvider
เป็นองค์ประกอบตัวช่วยในไลบรารีองค์ประกอบที่มีสไตล์ที่ให้การสนับสนุนชุดรูปแบบ องค์ประกอบตัวช่วยนี้จะแทรกธีมลงในองค์ประกอบ React ทั้งหมดด้านล่างผ่าน Context API
ในแผนผังการแสดงผล องค์ประกอบที่มีสไตล์ทั้งหมดจะมีสิทธิ์เข้าถึงธีมที่จัดเตรียมไว้ แม้ว่าจะอยู่ลึกหลายระดับก็ตาม ตรวจสอบส่วน "ชุดรูปแบบ"
ต่อไป เรานำเข้าเสื้อคลุม ./components/Globalstyle
จาก ./components/ GlobalStyle
สุดท้ายนี้ จากด้านบนสุด เรานำเข้าทั้งวัตถุ lightTheme
และ darkTheme
จาก ./components/ ./components/Themes
ในการสร้างวิธีการสลับ เราต้องการสถานะที่เก็บค่าสีเริ่มต้นของธีมของเรา ดังนั้นเราจึงสร้างสถานะของ theme
และตั้งค่าสถานะเริ่มต้นเป็น light
โดยใช้ useState
hook
ตอนนี้สำหรับฟังก์ชั่นการสลับ
เมธอด themeToggler
ใช้โอเปอเรเตอร์ ternary เพื่อตรวจสอบสถานะของ theme
และสลับระหว่างความมืดหรือสว่างตามค่าของเงื่อนไข
ThemeProvider
ซึ่งเป็นองค์ประกอบผู้ช่วยที่มีสไตล์ ล้อมทุกอย่างในคำสั่ง return
และแทรกส่วนประกอบใดๆ ด้านล่าง โปรดจำไว้ว่า GlobalStyles
ของเราใส่ สไตล์สากล ลงในส่วนประกอบของเรา ดังนั้นจึงถูกเรียกภายในองค์ประกอบห่อหุ้ม ThemeProvider
สุดท้ายนี้ เราได้สร้างปุ่มที่มีเหตุการณ์ onClick
ซึ่งกำหนดเมธอด themeToggler
ของเราให้กับมัน
มาดูผลลัพธ์กันก่อน
ไฟล์ App.js
ของเราต้องมีการ refactored; รหัสจำนวนมากไม่แห้ง (DRY ย่อมาจาก "อย่าพูดซ้ำ" ซึ่งเป็นหลักการพื้นฐานของการพัฒนาซอฟต์แวร์ที่มุ่งลดการทำซ้ำ) ตรรกะทั้งหมดดูเหมือนจะอยู่ใน App.js
; เป็นการดีที่จะแยกตรรกะของเราออกเพื่อความชัดเจน ดังนั้น เราจะสร้างส่วนประกอบที่จัดการฟังก์ชันการสลับ
สลับส่วนประกอบ
ยังอยู่ในโฟลเดอร์ components
ให้สร้างไฟล์ Toggler.js
และเพิ่มโค้ดต่อไปนี้ลงไป:
import React from 'react' import { func, string } from 'prop-types'; import styled from "styled-components" const Button = styled.button` background: ${({ theme }) => theme.background}; border: 2px solid ${({ theme }) => theme.toggleBorder}; color: ${({ theme }) => theme.text}; border-radius: 30px; cursor: pointer; font-size:0.8rem; padding: 0.6rem; } \`; const Toggle = ({theme, toggleTheme }) => { return ( <Button onClick={toggleTheme} > Switch Theme </Button> ); }; Toggle.propTypes = { theme: string.isRequired, toggleTheme: func.isRequired, } export default Toggle;
เพื่อให้ทุกอย่างเรียบร้อย เราได้จัดรูปแบบปุ่มสลับของเราในองค์ประกอบ Toggle
โดยใช้ฟังก์ชันที่ styled
จากองค์ประกอบที่มีสไตล์
นี่เป็นเพียงการนำเสนอเท่านั้น คุณสามารถจัดรูปแบบปุ่มได้ตามที่เห็นสมควร
ภายในองค์ประกอบ Toggle
เราส่งอุปกรณ์ประกอบฉากสองชิ้น:
-
theme
ให้ชุดรูปแบบปัจจุบัน (สว่างหรือมืด); - ฟังก์ชัน
toggleTheme
จะใช้เพื่อสลับระหว่างธีมต่างๆ
ต่อไป เราจะคืนค่าคอมโพเนนต์ Button
และกำหนดฟังก์ชัน toggleTheme
ให้กับเหตุการณ์ onClick
สุดท้ายนี้ เราใช้ propTypes
เพื่อกำหนดประเภทของเรา ตรวจสอบให้แน่ใจว่า theme
ของเราเป็น string
และ isRequired
ในขณะที่ toggleTheme
ของเราเป็น func
และ isRequired
การใช้ Custom Hooks ( useDarkMode
)
เมื่อสร้างแอปพลิเคชัน ความสามารถในการปรับขนาดเป็นสิ่งสำคัญยิ่ง ซึ่งหมายความว่าตรรกะทางธุรกิจของเราต้องนำมาใช้ใหม่ได้ เพื่อให้เราสามารถใช้งานได้ในหลายๆ ที่และแม้กระทั่งในโครงการต่างๆ
ด้วยเหตุนี้จึงเป็นการดีที่จะย้ายฟังก์ชันการสลับของเราไปยังส่วนประกอบที่แยกจากกัน สำหรับสิ่งนั้น เราจะสร้างเบ็ดที่กำหนดเอง
มาสร้างไฟล์ใหม่ที่ชื่อ useDarkMode.js
ในโฟลเดอร์ components
และย้ายตรรกะของเราไปที่ไฟล์นี้ด้วยการปรับแต่งบางอย่าง เพิ่มรหัสต่อไปนี้ในไฟล์:
import { useEffect, useState } from 'react'; export const useDarkMode = () => { const [theme, setTheme] = useState('light'); const setMode = mode => { window.localStorage.setItem('theme', mode) setTheme(mode) }; const themeToggler = () => { theme === 'light' ? setMode('dark') : setMode('light') }; useEffect(() => { const localTheme = window.localStorage.getItem('theme'); localTheme && setTheme(localTheme) }, []); return [theme, themeToggler] };
เราได้เพิ่มบางสิ่งที่นี่
-
setMode
เราใช้localStorage
เพื่อยืนยันระหว่างเซสชันในเบราว์เซอร์ ดังนั้น หากผู้ใช้เลือกธีมสีเข้มหรือสีอ่อน นั่นคือสิ่งที่พวกเขาจะได้รับเมื่อเข้าชมแอปในครั้งต่อไป หรือหากพวกเขาโหลดหน้าซ้ำ ดังนั้น ฟังก์ชันนี้จะตั้งค่าสถานะของเราและส่งtheme
ไปที่localStorage
-
themeToggler
ฟังก์ชันนี้ใช้ตัวดำเนินการ ternary เพื่อตรวจสอบสถานะของธีมและสลับความมืดหรือแสงตามความเป็นจริงของเงื่อนไข -
useEffect
เราได้ติดตั้งuseEffect
hook เพื่อตรวจสอบการติดตั้งส่วนประกอบ หากผู้ใช้ได้เลือกธีมไว้ก่อนหน้านี้ เราจะส่งต่อไปยังฟังก์ชันsetTheme
ของเรา ในท้ายที่สุด เราจะคืนtheme
ซึ่งประกอบด้วยtheme
ที่เลือกและฟังก์ชันthemeToggler
เพื่อสลับไปมาระหว่างโหมดต่างๆ
ฉันคิดว่าคุณจะเห็นด้วยว่าองค์ประกอบโหมดมืดของเราดูโฉบเฉี่ยว
ไปที่ App.js
เพื่อดูขั้นตอนสุดท้าย
import React, { useState, useEffect } from "react"; import {ThemeProvider} from "styled-components";
import {useDarkMode} from "./components/useDarkMode"
import { GlobalStyles } from "./components/Globalstyle"; import { lightTheme, darkTheme } from "./components/Themes" import Toggle from "./components/Toggler" import "./App.css"; import dummyData from "./data"; import CardList from "./components/CardList"; const App = () => { const [videos, setVideos] = useState([]);
const [theme, themeToggler] = useDarkMode(); const themeMode = theme === 'light' ? lightTheme : darkTheme;
useEffect(() => { const timer = setTimeout(() => { setVideos(dummyData); }, 1000); return () => clearTimeout(timer); }, []); return (
<ThemeProvider theme={themeMode}>
<> <GlobalStyles/> <div className="App">
<Toggle theme={theme} toggleTheme={themeToggler} />
{ videos.map((list, index) => { return ( <section key={index}> <h2 className="section-title">{list.section}</h2> <CardList list={list} /> <hr /> </section> ); })} </div> </> </ThemeProvider> ); }; export default App;
โค้ดที่เน้นสีถูกเพิ่มใหม่ไปยัง App.js
ขั้นแรก เรานำเข้า hook แบบกำหนดเองของเรา ทำลายโครงสร้างอุปกรณ์ประกอบฉากของ theme
และ themeToggler
และตั้งค่าด้วยฟังก์ชัน useDarkMode
โปรดทราบว่าเมธอด useDarkMode
จะแทนที่ สถานะ theme
ของเรา ซึ่งเดิมอยู่ใน App.js
เราประกาศตัวแปร themeMode
ซึ่งแสดงธีมสีอ่อนหรือสีเข้มตามเงื่อนไขของโหมด theme
ในขณะนั้น
ตอนนี้ คอมโพเนนต์ wrapper ThemeProvider
ของเราได้รับการกำหนดตัวแปร themeMode
ที่เพิ่งสร้างขึ้นเมื่อเร็วๆ นี้ให้กับพร็อพ theme
และสุดท้าย แทนที่ปุ่มปกติ เราส่งผ่านองค์ประกอบ Toggle
โปรดจำไว้ว่าในองค์ประกอบ Toggle
ของเรา เราได้กำหนดและจัดรูปแบบปุ่ม และส่งทั้ง theme
และ toggleTheme
ไปเป็นอุปกรณ์ประกอบฉาก ดังนั้น สิ่งที่เราต้องทำคือส่งอุปกรณ์ประกอบฉากเหล่านี้อย่างเหมาะสมไปยังองค์ประกอบ Toggle
ซึ่งจะทำหน้าที่เป็นปุ่มของเราใน App.js
ใช่! โหมดมืดของเราได้รับการตั้งค่าและยังคงอยู่โดยไม่เปลี่ยนสีเมื่อรีเฟรชหรือเข้าชมหน้าในแท็บใหม่
ลองดูผลลัพธ์ในการดำเนินการ:
เกือบทุกอย่างทำงานได้ดี แต่มีสิ่งหนึ่งที่เราทำได้เพื่อทำให้ประสบการณ์ของเรายอดเยี่ยม เปลี่ยนเป็นธีมสีเข้มแล้วโหลดหน้าซ้ำ คุณเห็นว่าสีน้ำเงินในปุ่มโหลดก่อนสีเทาในช่วงเวลาสั้น ๆ หรือไม่? ที่เกิดขึ้นเนื่องจากตะขอ useState
ของเราเริ่มต้นธีม light
ในขั้นต้น หลังจากนั้น useEffect
จะทำงาน ตรวจสอบ localStorage
จากนั้นตั้งค่า theme
เป็น dark
ข้ามไปที่ hook ที่กำหนดเองของเรา useDarkMode.js
และเพิ่มโค้ดเล็กน้อย:
import { useEffect, useState } from 'react'; export const useDarkMode = () => { const [theme, setTheme] = useState('light');
const [mountedComponent, setMountedComponent] = useState(false)
const setMode = mode => { window.localStorage.setItem('theme', mode) setTheme(mode) }; const themeToggler = () => { theme === 'light' ? setMode('dark') : setMode('light') }; useEffect(() => { const localTheme = window.localStorage.getItem('theme'); localTheme ? setTheme(localTheme) : setMode('light')
setMountedComponent(true)
}, []); return [theme, themeToggler,
}, []); return [theme, themeToggler,
mountedComponent
]
};
โค้ดที่ไฮไลต์เป็นเพียงโค้ดเดียวที่เพิ่มใน useDarkMode.js
เราได้สร้างสถานะอื่นชื่อ mountedComponent
และตั้งค่าเริ่มต้น false
โดยใช้ useState
hook ถัดไป ภายใน useEffect
hook เราตั้งค่าสถานะ mountedComponent
true
โดยใช้ setMountedComponent
สุดท้าย ในอาร์เรย์ return
เรารวมสถานะ mountedComponent
สุดท้าย มาเพิ่มโค้ดเล็กน้อยใน App.js
เพื่อให้ทุกอย่างทำงานได้
import React, { useState, useEffect } from "react"; import {ThemeProvider} from "styled-components"; import {useDarkMode} from "./components/useDarkMode" import { GlobalStyles } from "./components/Globalstyle"; import { lightTheme, darkTheme } from "./components/Themes" import Toggle from "./components/Toggler" import "./App.css"; import dummyData from "./data"; import CardList from "./components/CardList"; const App = () => { const [videos, setVideos] = useState([]);
const [theme, themeToggler, mountedComponent] = useDarkMode();
const themeMode = theme === 'light' ? lightTheme : darkTheme; useEffect(() => { const timer = setTimeout(() => { setVideos(dummyData); }, 1000); return () => clearTimeout(timer); }, []);
if(!mountedComponent) return <div/>
return ( <ThemeProvider theme={themeMode}> <> <GlobalStyles/> <div className="App"> <Toggle theme={theme} toggleTheme={themeToggler} /> { videos.map((list, index) => { return ( <section key={index}> <h2 className="section-title">{list.section}</h2> <CardList list={list} /> <hr /> </section> ); })} </div> </> </ThemeProvider> ); }; export default App;
เราได้เพิ่มสถานะ mountedComponent
ของเราเป็นส่วนประกอบในเบ็ด useDarkMode
ของเรา และเราได้ตรวจสอบว่าคอมโพเนนต์ของเราได้ติดตั้งแล้วหรือไม่ เพราะนี่คือสิ่งที่เกิดขึ้นในเบ็ด useEffect
หากยังไม่เกิดขึ้น เราจะสร้าง div
ที่ว่างเปล่า
มาดูผลลัพธ์ของหน้าเว็บโหมดมืดของเรากัน
ตอนนี้ คุณจะสังเกตเห็นว่าในขณะที่อยู่ในโหมดมืด เมื่อหน้าโหลดซ้ำ สีของปุ่มจะไม่เปลี่ยนแปลง
บทสรุป
โหมดมืดกลายเป็นความชอบของผู้ใช้มากขึ้นเรื่อยๆ และการใช้งานในเว็บแอป React นั้นง่ายกว่ามากเมื่อใช้แรปเปอร์ธีม ThemeProvider
ในองค์ประกอบที่มีสไตล์ ไปข้างหน้าและทดลองกับองค์ประกอบที่มีสไตล์เมื่อคุณใช้โหมดมืด คุณสามารถเพิ่มไอคอนแทนปุ่มได้
โปรดแชร์ความคิดเห็นและประสบการณ์ของคุณเกี่ยวกับคุณลักษณะการจัดรูปแบบในองค์ประกอบที่มีสไตล์ในส่วนความคิดเห็นด้านล่าง ฉันชอบที่จะเห็นสิ่งที่คุณคิด!
พื้นที่เก็บข้อมูลสนับสนุนสำหรับบทความนี้มีอยู่ใน GitHub นอกจากนี้ ตรวจสอบออกใน CodeSandbox
อ้างอิง
- “เอกสารประกอบ” ส่วนประกอบที่มีสไตล์
- “สร้างโหมดมืดของแอปโดยใช้ส่วนประกอบที่มีสไตล์”, Tom Nolan, Medium