Det har blivit populärt för applikationer att ha en inställning som låter dig växla mellan mörkt och ljust läge. Kanske beror det på populariteten hos mörka användargränssnitt, kanske beror det på att appar gradvis blir mer konfigurerbara.

React context är ett enkelt sätt att dela data globalt, men det kan göra komponentåteranvändning svårare. Som ett alternativ kan du bygga en mörklägesknappkomponent som använder useEffect- och useState-krokarna istället för kontext. Det kommer att växla ett dataattribut på body-elementet som CSS-stilar kan riktas mot.

Vad du behöver

För att följa med i denna handledning behöver du följande:

  • En ny version av Node installerad på din maskin.
  • En grundläggande förståelse för React och Reagera krokar.
  • Ett starter React-projekt. Bara skapa en React-app och du är redo att gå.

Skapa en knappkomponent

Knappkomponenten kommer att ansvara för att växla temat från mörkt till ljust. I ett riktigt program kan den här knappen vara en del av Navbar-komponenten.

Skapa en ny fil som heter Button.js i src-mappen och lägg till följande kod.

instagram viewer
importera { useState } från 'reagera'

exporterastandardfungeraKnapp() {
const [theme, settheme] = useState("mörk")

konst handleToggle = () => {
const newTheme = tema "ljus"? "mörk": "ljus"
settheme (nytttema)
}
lämna tillbaka (
<>
<knappen klassnamn="temaBtn" onClick={handleToggle}>
{tema "ljus"? <spänna>mörk</span>: <spänna>ljus</span>}
</button>
</>
)
}

Importera först useState()-kroken från React. Du kommer att använda den för att hålla reda på det aktuella temat.

Initiera tillståndet till mörkt i knappkomponenten. Funktionen handleToggle() tar hand om växlingsfunktionen. Den körs varje gång du klickar på knappen.

Den här komponenten växlar också knapptexten när den ändrar tema.

För att visa Button-komponenten importera den till App.js.

importera Knapp från './Knapp';
fungeraApp() {
lämna tillbaka (
<div>
<Knapp/>
</div>
);
}

exporterastandard App;

Skapa CSS-stilar

Just nu ändrar inte gränssnittet för React-appen att klicka på knappen. För det måste du först skapa CSS-stilarna för mörkt och ljust läge.

Lägg till följande i App.css.

kropp {
--färg-text-primär: #131616;
--färg-text-sekundär: #ff6b00;
--color-bg-primary: #E6EDEE;
--färg-bg-sekundär: #7d86881c;
bakgrund: var(--färg-bg-primär);
Färg: var(--färg-text-primär);
övergång: bakgrund 0.25slätta-in-ut;
}
body[data-theme="ljus"] {
--färg-text-primär: #131616;
--color-bg-primary: #E6EDEE;
}
body[data-theme="mörk"] {
--färg-text-primär: #F2F5F7;
--color-bg-primary: #0E141B;
}

Här definierar du stilarna för body-elementet med hjälp av dataattribut. Det finns dataattributet ljust tema och dataattributet mörkt tema. Var och en av dem har CSS-variabler med olika färger. Genom att använda CSS-dataattribut kan du byta stilar enligt data. Om en användare väljer ett mörkt tema kan du ställa in kroppsdataattributet till mörkt och användargränssnittet kommer att ändras.

Du kan också modifiera knappelementstilarna så att de ändras med temat.

.themeBtn {
stoppning: 10px;
Färg: var(--färg-text-primär);
bakgrund: transparent;
gräns: 1px fast var(--färg-text-primär);
markör: pekare;
}

Ändra knappkomponent för att växla mellan stilar

För att växla mellan stilarna som definieras i CSS-filen måste du ställa in data i body-elementet i handleToggle()-funktionen.

I Button.js, ändra handleToggle() så här:

konst handleToggle = () => {
const newTheme = tema "ljus"? "mörk": "ljus"
settheme (nytttema)
dokumentera.body.dataset.theme = tema
}

Om du klickar på knappen ska bakgrunden växla från mörk till ljus eller ljus till mörk. Men om du uppdaterar sidan återställs temat. För att fortsätta med temainställningen, lagra temainställningen i lokalt utrymme.

Beständiga användarpreferenser i lokal lagring

Du bör hämta användarpreferensen så snart Button-komponenten återges. UseEffect()-kroken är perfekt för detta eftersom den körs efter varje rendering.

Innan du hämtar temat från den lokala lagringen måste du först lagra det.

Skapa en ny funktion som heter storeUserPreference() i Button.js.

konst storeUserSetPreference = (pref) => {
localStorage.setItem("tema", pref);
};

Denna funktion tar emot användarpreferensen som ett argument och lagrar den som ett objekt som kallas tema.

Du kommer att anropa denna funktion varje gång användaren växlar temat. Så, ändra handleToggle()-funktionen så att den ser ut så här:

konst handleToggle = () => {
const newTheme = tema "ljus"? "mörk": "ljus"
settheme (nytttema)
storeUserSetPreference (newTheme)
dokumentera.body.dataset.theme = tema
}

Följande funktion hämtar temat från lokal lagring:

konst getUserSetPreference = () => {
returnera localStorage.getItem("tema");
};

Du kommer att använda den i useEffect-kroken så varje gång komponenten renderas hämtar den inställningen från lokal lagring för att uppdatera temat.

useEffect(() => {
konst userSetPreference = getUserSetPreference();

if (userSetPreference) {
settheme (userSetPreference)
}
dokumentera.body.dataset.theme = tema
}, [tema])

Få användarinställningar från webbläsarinställningar

För en ännu bättre användarupplevelse kan du använda föredrar-färgschema CSS-mediafunktion för att ställa in temat. Detta bör återspegla en användares systeminställningar som de kan kontrollera via sitt operativsystem eller webbläsare. Inställningen kan antingen vara ljus eller mörk. I din applikation måste du kontrollera denna inställning omedelbart efter att knappkomponenten laddas. Detta innebär att du implementerar denna funktion i useEffect()-kroken.

Skapa först en funktion som hämtar användarpreferensen.

Lägg till följande i Button.js.

konst getMediaQueryPreference = () => {
const mediaQuery = "(föredrar-färgschema: mörk)";
konst mql = fönster.matchMedia (mediaQuery);
konst hasPreference = sorts mql.matches "boolean";

if (hasPreference) {
returnera mql.matches? "mörk": "ljus";
}
};

Ändra sedan useEffect()-kroken för att hämta mediefråga-inställningen och använd den om inget tema är inställt i den lokala lagringen.

useEffect(() => {
konst userSetPreference = getUserSetPreference();
konst mediaQueryPreference = getMediaQueryPreference();

if (userSetPreference) {
settheme (userSetPreference)
} annan {
settheme (mediaQueryPreference)
}

dokumentera.body.dataset.theme = tema
}, [tema])

Om du startar om din applikation bör temat matcha systemets inställningar.

Använd React Context för att växla mörkt läge

Du kan använda dataattribut, CSS och React hooks för att växla temat för en React-applikation.

Ett annat tillvägagångssätt för att hantera mörkt läge i React är att använda context API. React-kontext låter dig dela data över komponenter utan att behöva skicka det genom rekvisita. När du använder den för att växla teman skapar du en temakontext som du kan komma åt i hela applikationen. Du kan sedan använda temavärdet för att tillämpa matchande stilar.

Även om detta tillvägagångssätt fungerar, är det enklare att använda CSS-dataattribut.