Implementieren des Dunkelmodus in React-Apps mithilfe von styled-components
Veröffentlicht: 2022-03-10Eine der am häufigsten nachgefragten Softwarefunktionen ist der Dunkelmodus (oder Nachtmodus, wie andere ihn nennen). Wir sehen den Dunkelmodus in den Apps, die wir jeden Tag verwenden. Von mobilen bis hin zu Web-Apps ist der Dunkelmodus für Unternehmen, die sich um die Augen ihrer Benutzer kümmern möchten, unverzichtbar geworden.
Der Dunkelmodus ist eine zusätzliche Funktion, die hauptsächlich dunkle Oberflächen in der Benutzeroberfläche anzeigt. Die meisten großen Unternehmen (wie YouTube, Twitter und Netflix) haben den Dunkelmodus in ihren Mobil- und Web-Apps eingeführt.
Wir werden zwar nicht weiter auf React und Styled-Components eingehen, aber Grundkenntnisse in React, CSS und Styled-Components wären von Vorteil. Dieses Tutorial wird denjenigen zugutekommen, die ihre Webanwendungen verbessern möchten, indem sie sich an diejenigen richten, die den dunklen Modus lieben.

Einige Tage vor dem Schreiben dieses Artikels kündigte StackOverflow die Veröffentlichung des Dunkelmodus an, der den Benutzern die Möglichkeit gibt, zwischen den beiden Modi umzuschalten.
Der Dunkelmodus reduziert die Belastung der Augen und hilft, wenn Sie längere Zeit an einem Computer oder Mobiltelefon arbeiten.
Was ist der dunkle Modus?
Der Dunkelmodus ist das Farbschema jeder Benutzeroberfläche, die hellen Text und Elemente der Benutzeroberfläche auf einem dunklen Hintergrund anzeigt, wodurch der Bildschirm auf Mobiltelefonen, Tablets und Computern etwas einfacher zu sehen ist. Der Dunkelmodus reduziert das vom Bildschirm emittierte Licht, während die für die Lesbarkeit erforderlichen Mindestfarbkontrastverhältnisse beibehalten werden.
Warum sollten Sie sich für den Dunkelmodus interessieren?
Der Dunkelmodus verbessert die visuelle Ergonomie, indem er die Belastung der Augen verringert, den Bildschirm an die aktuellen Lichtverhältnisse anpasst und die Verwendung bei Nacht oder in dunklen Umgebungen erleichtert.
Bevor wir den Dunkelmodus in unserer App implementieren, schauen wir uns seine Vorteile an.
Batterieschonung
Der Dunkelmodus in Web- und mobilen Apps kann die Akkulaufzeit eines Geräts verlängern. Google hat bestätigt, dass der Dunkelmodus auf OLED-Bildschirmen eine große Hilfe für die Akkulaufzeit war.
Beispielsweise spart der Dunkelmodus in der YouTube-App bei 50 % Helligkeit etwa 15 % mehr Bildschirmenergie als ein flacher weißer Hintergrund. Bei 100 % Bildschirmhelligkeit spart die dunkle Oberfläche satte 60 % Bildschirmenergie.
Der dunkle Modus ist wunderschön
Der Dunkelmodus ist schön und kann die Attraktivität des Bildschirms erheblich verbessern.
Während die meisten Produkte auf einen ähnlichen, schlichten weißen Look setzen, bietet der Dark Mode etwas anderes, das sich mysteriös und neu anfühlt.
Es bietet auch großartige Möglichkeiten, grafische Inhalte wie Dashboards, Bilder und Fotos auf frische Weise zu präsentieren.

Nachdem Sie nun wissen, warum Sie den Dunkelmodus in Ihrer nächsten Webanwendung implementieren sollten, lassen Sie uns tief in die Stilkomponenten eintauchen, die die entscheidende Ressource dieses Tutorials darstellen.
Der Dunkelmodus ist das Farbschema jeder Benutzeroberfläche, die hellen Text und Elemente der Benutzeroberfläche auf einem dunklen Hintergrund anzeigt, wodurch die Anzeige auf Mobiltelefonen, Tablets und Computern etwas einfacher wird.
„
Was sind gestylte Komponenten?
In diesem Artikel werden wir die styled-components-Bibliothek sehr oft verwenden. Es gab schon immer viele Möglichkeiten, eine moderne Web-App zu gestalten. Es gibt die traditionelle Methode des Stylens auf Dokumentebene, die das Erstellen einer index.css
-Datei und das Verknüpfen mit dem HTML-Code oder das Stylen innerhalb der HTML-Datei umfasst.
Seit der Einführung von CSS-in-JS hat sich in letzter Zeit viel in der Art und Weise geändert, wie Web-Apps gestylt werden.
CSS-in-JS bezieht sich auf ein Muster, bei dem CSS mithilfe von JavaScript zusammengesetzt wird. Es verwendet gekennzeichnete Vorlagenliterale, um Komponenten in einer JavaScript-Datei zu formatieren.
Um mehr über CSS-in-JS zu erfahren, lesen Sie den Artikel von Anna Monus zu diesem Thema.
styled-components ist eine CSS-in-JS-Bibliothek, mit der Sie alle Funktionen von CSS verwenden können, die Sie lieben, einschließlich Medienabfragen, Pseudo-Selektoren und Verschachtelung.
Warum styled-components?
styled-components wurde aus folgenden Gründen erstellt:
- Kein Klassenname Hölle
Anstatt sich den Kopf zu kratzen, um einen Klassennamen für ein Element zu finden, generiert styled-components eindeutige Klassennamen für Ihre Stile. Sie müssen sich keine Sorgen über Rechtschreibfehler oder die Verwendung von Klassennamen machen, die keine Bedeutung haben. - Verwendung von Requisiten
styled-components ermöglichen es uns, Styling-Eigenschaften mit demprops
-Parameter zu erweitern, der häufig in React verwendet wird – und so das Feeling einer Komponente über den Status der Anwendung dynamisch beeinflusst. - Unterstützt Sass-Syntax
Mit Styled-Components ist es möglich, Sass-Syntax sofort zu schreiben, ohne Präprozessoren oder zusätzliche Build-Tools einrichten zu müssen. In Ihren Stildefinitionen können Sie das&
-Zeichen verwenden, um auf die aktuelle Komponente abzuzielen, Pseudoselektoren verwenden und mit Verschachtelungen experimentieren. - Thematisierung
styled-components bieten vollständige Designunterstützung, indem sie eineThemeProvider
Wrapper-Komponente exportieren. Diese Komponente stellt über die Kontext-API ein Design für alle React-Komponenten bereit. In der Rendering-Struktur haben alle gestalteten Komponenten Zugriff auf das bereitgestellte Thema, selbst wenn sie mehrere Ebenen tief sind. Im weiteren Verlauf dieses Tutorials werden wir uns eingehender mit den Designfunktionen von Styled-Components befassen.
Um mehr über die Vorteile von Styled-Components zu erfahren, lesen Sie den Artikel von Kris Guzman.
Implementierung des Dunkelmodus
In diesem Artikel werden wir den Dunkelmodus auf einer einfachen YouTube-ähnlichen Webseite implementieren.
Um mitzumachen, stellen Sie sicher, dass Sie das ursprüngliche Repository aus dem starter
Zweig klonen.
Einrichten
Lassen Sie uns alle Abhängigkeiten in unserer Datei package.json
installieren. Führen Sie im Terminal den folgenden Befehl aus:
npm install
Führen Sie nach erfolgreicher Installation npm start
aus. So sieht die Webseite ohne implementierten Dunkelmodus aus.

Um styled-components
zu installieren, führen Sie in Ihrem Terminal npm install styled-components
.
Implementierung
Um den Dunkelmodus zu implementieren, müssen wir vier verschiedene Komponenten erstellen.
-
Theme
Diese enthält die Farbeigenschaften unserer hellen und dunklen Themen. -
GlobalStyles
Diese enthält die globalen Stile für das gesamte Dokument. -
Toggler
Dies enthält das Schaltflächenelement, das die Funktionalität umschaltet. -
useDarkMode
Dieser benutzerdefinierte Hook behandelt die Logik hinter der Änderung des Designs und die Persistenz unseres Designs in localStorage.
Themenkomponente
Im src
Ordner sehen Sie Komponenten im components
. Erstellen Sie eine Themes.js
-Datei und fügen Sie ihr den folgenden Code hinzu.
export const lightTheme = { body: '#FFF', text: '#363537', toggleBorder: '#FFF', background: '#363537', } export const darkTheme = { body: '#363537', text: '#FAFAFA', toggleBorder: '#6B8096', background: '#999', }
Hier haben wir lightTheme
und darkTheme
Objekte mit unterschiedlichen Farbvariablen definiert und exportiert. Fühlen Sie sich frei, zu experimentieren und die Variablen an Ihre Bedürfnisse anzupassen.
globalStyles-Komponente
Erstellen Sie im Ordner „ components
“ eine globalStyles.js
-Datei und fügen Sie den folgenden Code hinzu:
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; } `
Wir haben createGlobalStyle
aus styled-components importiert. Die createGlobalStyle
Methode ersetzt die inzwischen veraltete injectGlobal-Methode aus styled-components Version 3. Diese Methode generiert eine React-Komponente, die, wenn sie zu Ihrem Komponentenbaum hinzugefügt wird, globale Stile in das Dokument einfügt, in unserem Fall App.js
.
Wir haben eine GlobalStyle
-Komponente definiert und den Werten aus dem Themenobjekt background
und color
zugewiesen. Daher ändern sich die Werte jedes Mal, wenn wir den Schalter umschalten, abhängig von den dunklen oder hellen Designobjekten, die wir an ThemeProvider
(die später erstellt werden, wenn wir fortfahren).
Die Übergangseigenschaft von 0.50s
ermöglicht es, dass diese Änderung etwas reibungsloser erfolgt, sodass wir beim Hin- und Herschalten sehen können, wie die Änderungen stattfinden.
Erstellen einer Designumschaltfunktion
Um die Theme-Toggle-Funktionalität zu implementieren, müssen wir nur ein paar Codezeilen hinzufügen. Fügen Sie in der Datei App.js
den folgenden Code hinzu (beachten Sie, dass Sie den hervorgehobenen Code hinzufügen sollten):
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;
Der hervorgehobene Code ist der neu zu App.js
hinzugefügte Code. Wir haben ThemeProvider
aus styled-components
importiert. ThemeProvider
ist eine Hilfskomponente in der styled-components-Bibliothek, die Designunterstützung bereitstellt. Diese Hilfskomponente fügt über die Kontext-API ein Thema in alle React-Komponenten unter sich ein.
In der Rendering-Struktur haben alle gestalteten Komponenten Zugriff auf das bereitgestellte Thema, selbst wenn sie mehrere Ebenen tief sind. Sehen Sie sich den Abschnitt „Themen“ an.
Als nächstes importieren wir den GlobalStyle
-Wrapper aus ./components/Globalstyle
. Zuletzt importieren wir von oben sowohl die lightTheme
als auch die darkTheme
Objekte aus ./components/Themes
.

Damit wir eine Umschaltmethode erstellen können, benötigen wir einen Zustand, der den anfänglichen Farbwert unseres Themas enthält. Also erstellen wir einen theme
und setzen den Anfangszustand auf light
, indem wir den useState
Hook verwenden.
Nun zur Umschaltfunktion.
Die themeToggler
Methode verwendet einen ternären Operator, um den Zustand des theme
zu überprüfen, und schaltet je nach Wert der Bedingung entweder dunkel oder hell um.
ThemeProvider
, eine Hilfskomponente für formatierte Komponenten, schließt alles in die return
-Anweisung ein und fügt alle Komponenten darunter ein. Denken Sie daran, dass unsere GlobalStyles
globale Stile in unsere Komponenten einfügen; Daher wird es innerhalb der ThemeProvider
Wrapper-Komponente aufgerufen.
Zuletzt haben wir eine Schaltfläche mit einem onClick
-Ereignis erstellt, das ihr unsere themeToggler
Methode zuweist.
Sehen wir uns das bisherige Ergebnis an.

Unsere App.js
-Datei muss umgestaltet werden; ein Großteil seines Codes ist nicht DRY. (DRY steht für „don’t repeat yourself“, ein Grundprinzip der Softwareentwicklung, das darauf abzielt, Wiederholungen zu reduzieren.) Die gesamte Logik scheint in App.js
zu liegen; Es ist eine gute Praxis, unsere Logik der Klarheit halber zu trennen. Wir erstellen also eine Komponente, die die Umschaltfunktion übernimmt.
Toggle-Komponente
Erstellen Sie noch im components
eine Toggler.js
-Datei und fügen Sie den folgenden Code hinzu:
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;
Um die Dinge ordentlich zu halten, haben wir unseren Toggle-Button in der Toggle
-Komponente gestaltet, indem wir die styled
-Funktion von styled-components verwendet haben.
Dies dient lediglich der Präsentation; Sie können die Schaltfläche so gestalten, wie Sie es für richtig halten.
Innerhalb der Toggle
Komponente übergeben wir zwei Requisiten:
- das
theme
stellt das aktuelle Thema bereit (hell oder dunkel); - Die
toggleTheme
Funktion wird verwendet, um zwischen Themen zu wechseln.
Als Nächstes geben wir die Button
-Komponente zurück und weisen dem onClick
Event eine toggleTheme
Funktion zu.
Schließlich verwenden wir propTypes
, um unsere Typen zu definieren, und stellen sicher, dass unser theme
ein string
und isRequired
ist, während unser toggleTheme
func
isRequired
ist.
Benutzerdefinierte Hooks verwenden ( useDarkMode
)
Beim Erstellen einer Anwendung ist die Skalierbarkeit von größter Bedeutung, was bedeutet, dass unsere Geschäftslogik wiederverwendbar sein muss, damit wir sie an vielen Stellen und sogar in verschiedenen Projekten verwenden können.
Aus diesem Grund wäre es großartig, unsere Toggle-Funktionalität in eine separate Komponente zu verschieben. Dafür würden wir unseren eigenen benutzerdefinierten Haken erstellen.
Lassen Sie uns eine neue Datei namens useDarkMode.js
im Ordner „ components
“ erstellen und unsere Logik mit einigen Anpassungen in diese Datei verschieben. Fügen Sie der Datei den folgenden Code hinzu:
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] };
Wir haben hier einiges hinzugefügt.
-
setMode
Wir verwendenlocalStorage
, um zwischen Sitzungen im Browser zu bestehen. Wenn ein Benutzer also das dunkle oder helle Design ausgewählt hat, wird ihm dies bei seinem nächsten Besuch in der App oder beim erneuten Laden der Seite angezeigt. Daher setzt diese Funktion unseren Zustand und übergibt dastheme
anlocalStorage
. -
themeToggler
Diese Funktion verwendet einen ternären Operator, um den Zustand des Themas zu überprüfen, und schaltet je nach Wahrheit der Bedingung entweder dunkel oder hell um. -
useEffect
Wir haben denuseEffect
Hook implementiert, um die Komponentenmontage zu überprüfen. Wenn der Benutzer zuvor ein Thema ausgewählt hat, übergeben wir es an unseresetTheme
Funktion. Am Ende geben wir unsertheme
zurück, das das gewähltetheme
und die FunktionthemeToggler
zum Umschalten zwischen den Modi enthält.
Ich denke, Sie werden mir zustimmen, dass unsere Dark-Mode-Komponente elegant aussieht.
Lassen Sie uns für den letzten Schliff zu 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;
Der hervorgehobene Code wird neu zu App.js
hinzugefügt.
Zuerst importieren wir unseren benutzerdefinierten Hook, destrukturieren das theme
und die themeToggler
Requisiten und setzen es mit der useDarkMode
Funktion.
Beachten Sie, dass die Methode useDarkMode
unseren theme
ersetzt , der ursprünglich in App.js
war.
Wir deklarieren eine themeMode
Variable, die entweder ein helles oder ein dunkles Design darstellt, basierend auf der Bedingung des theme
zu diesem Zeitpunkt.
Nun wird unserer ThemeProvider
Wrapper-Komponente unsere gerade erst erstellte themeMode
Variable dem theme
Prop zugewiesen.
Und schließlich übergeben wir anstelle des regulären Buttons die Toggle
Komponente.
Denken Sie daran, dass wir in unserer Toggle
-Komponente eine Schaltfläche definiert und gestylt und sowohl theme
als toggleTheme
als Requisiten an sie übergeben haben. Wir müssen diese Requisiten also nur entsprechend an die Toggle
-Komponente übergeben, die als unsere Schaltfläche in App.js
.
Jawohl! Unser dunkler Modus ist eingestellt und bleibt bestehen, ohne die Farbe zu ändern, wenn die Seite aktualisiert oder in einem neuen Tab besucht wird.
Sehen wir uns das Ergebnis in Aktion an:

Fast alles funktioniert gut, aber es gibt eine kleine Sache, die wir tun können, um unsere Erfahrung großartig zu machen. Wechseln Sie zum dunklen Design und laden Sie die Seite neu. Sehen Sie, dass die blaue Farbe in der Schaltfläche für einen kurzen Moment vor der grauen Farbe geladen wird? Das passiert, weil unser useState
Hook zunächst das light
Theme initiiert. Danach wird useEffect
, überprüft localStorage
und setzt erst dann das theme
auf dark
. Lassen Sie uns zu unserem benutzerdefinierten Hook useDarkMode.js
und ein wenig Code hinzufügen:
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
]
};
Der hervorgehobene Code ist der einzige, der zu useDarkMode.js
hinzugefügt wurde. Wir haben einen weiteren Status namens mountedComponent
“ erstellt und den Standardwert mithilfe des useState
-Hooks auf „ false
“ gesetzt. Als Nächstes setzen wir innerhalb des useEffect
-Hooks den mountedComponent
-Status mithilfe setMountedComponent
auf true
. Schließlich schließen wir in das return
den Zustand der mountedComponent
ein.
Zum Schluss fügen wir ein wenig Code in App.js
, damit alles funktioniert.
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;
Wir haben unseren mountedComponent
-Status als Prop in unserem useDarkMode
Hook hinzugefügt und wir haben überprüft, ob unsere Komponente gemountet wurde, denn genau das passiert im useEffect
Hook. Wenn es noch nicht passiert ist, rendern wir ein leeres div
.
Sehen wir uns das Ergebnis unserer Dunkelmodus-Webseite an.

Nun werden Sie feststellen, dass sich die Farbe der Schaltfläche im Dunkelmodus beim Neuladen der Seite nicht ändert.
Fazit
Der Dunkelmodus wird zunehmend zu einer Benutzerpräferenz, und die Implementierung in einer React-Web-App ist viel einfacher, wenn der ThemeProvider
-Theming-Wrapper in gestylten Komponenten verwendet wird. Machen Sie weiter und experimentieren Sie mit gestylten Komponenten, während Sie den Dunkelmodus implementieren. Sie könnten Symbole anstelle einer Schaltfläche hinzufügen.
Bitte teilen Sie Ihr Feedback und Ihre Erfahrungen mit der Designfunktion in gestylten Komponenten im Kommentarbereich unten. Ich würde gerne sehen, was Sie sich einfallen lassen!
Das unterstützende Repository für diesen Artikel ist auf GitHub verfügbar. Probieren Sie es auch auf CodeSandbox aus.
Verweise
- „Dokumentation“, gestylte Komponenten
- „Erstellen Sie einen dunklen Modus Ihrer App mit Styled Components“, Tom Nolan, Medium