Before we start I suggest you take a look at this post, we'll be using that same approach but with React.
Let us get started with a simple React component called App
:
import React from 'react'
import './styles.css'
function App() {
return (
<div className="App">
<h1>Hello stranger!</h1>
<h2>Lets persist our dark theme, shall we?</h2>
</div>
)
}
export default App
Now lets use useState
to set our default value for darkMode
, which will be false
:
import React, { useState } from "react";
import "./styles.css";
function App() {
const [darkMode, setDarkMode] = useState(false);
// ...
Now, lets change our div
to include a data-theme
attribute, we'll check if the value of darkMode
is true
and set a value of dark
, otherwise it's light
:
// ...
function App() {
return (
<div className="App" data-theme={darkMode ? 'dark' : 'light'}>
<h1>Hello stranger!</h1>
<h2>Lets persist our dark theme, shall we?</h2>
</div>
)
}
// ...
Now if you change our useState()
from false
to true
you should see that it sets the background of .App
to black and the text color to white.
Switch
Let us build a switch between dark and light mode. We can start by adding a new function that sets our theme either to light
or to dark
mode:
import React, { useState } from "react";
import "./styles.css";
function App() {
const [darkMode, setDarkMode] = useState(false);
const toggleDarkMode = () => setDarkMode(darkMode ? false : true);
// ...
We can still use a little trick on darkMode ? false : true
, we can change it to !darkMode
, what does this means?
Since darkMode
is a boolean we're saying we want the opposite value, see the output:
var darkMode = true
darkMode = !darkMode // false
darkMode = !darkMode // true
darkMode = !darkMode // false
darkMode = !darkMode // true
We can do this all day!
Button Switcher
Now that we have our toggleDarkMode
function in place let us create a <button>
to use it:
function App() {
return (
<div className="App" data-theme={darkMode ? 'dark' : 'light'}>
<button onClick={toggleDarkMode}>Dark mode toggler</button>
<h1>Hello stranger!</h1>
<h2>Lets persist our dark theme, shall we?</h2>
</div>
)
}
If you try it out is should work just fine, switching from light
to dark
mode and vice-versa. We can still use our darkMode
state to manipulate what the button displays:
<button onClick={toggleDarkMode}>
{darkMode ? 'Lights ON!' : 'Lights OFF!'}
</button>
Let us move on.
Persist
This is all good, but what if you switch to dark mode and refresh the page? We're back to light mode. Let us fix that shall we?
For that we'll be using React's useEffect
and localStorage
. First we need to import:
import React, { useState, useEffect } from 'react'
With useEffect
we can run some code every time a value changes, in this case we want to run our code when darkMode
changes:
import React, { useState, useEffect } from "react";
import "./styles.css";
function App() {
const [darkMode, setDarkMode] = useState(false);
const toggleDarkMode = () => setDarkMode(darkMode ? false : true);
useEffect(() => {
console.log(`Is in dark mode? ${darkMode}`);
}, [darkMode]);
// ...
If you check the console you'll see what's happening every time we toggle dark mode. Now that we know this is working we can store our value in localStorage
:
useEffect(() => {
console.log(`Is in dark mode? ${darkMode}`)
localStorage.setItem('DARK_MODE', darkMode)
}, [darkMode])
Alright, all good so far, now we just need read the value of DARK_MODE
from localStorage
and set our default darkMode
value:
const storedDarkMode = localStorage.getItem('DARK_MODE')
const [darkMode, setDarkMode] = useState(storedDarkMode)
Give it a try, change to dark mode and then refresh your page. Boom ๐ฅ
That's all, hope it helped you in some way.