'Unable to make persistent icons in dark mode toggle react js
So the these following lines of code handle my dark theme change
index.js
import React, {useState} from 'react'
import { FaRegMoon, FaRegSun } from "react-icons/fa"
import "./index.scss"
const ThemeToggle = () => {
const icon_size = 30;
const [icon, setIcon] = useState('FaRegSun')
const changeTheme = (iconName) => {
const item = localStorage.getItem("theme")
let theme;
if (item === "dark") {
theme = "";
localStorage.setItem('theme', "")
} else {
theme = "dark"
localStorage.setItem('theme', 'dark')
}
localStorage.setItem('theme', theme)
document.body.className = localStorage.getItem("theme");
setIcon(iconName)
}
const themeIsLight = (icon === 'FaRegMoon')
const Icon = themeIsLight ? <FaRegSun size={icon_size} onClick={() => changeTheme('FaRegSun') }/> : <FaRegMoon size={icon_size} onClick={() => changeTheme('FaRegMoon') }/>
return (
<div className="icon">
{Icon}
</div>
)
}
export default ThemeToggle;
and this is the App.tsx to make the theme persistant
import React from 'react';
import './App.sass';
import { Routes, Route } from 'react-router-dom';
import Layout from './components/Layout';
import Home from './components/Home';
function App() {
// makes the theme persist by getting the item theme from local storage
// converting to string and assigning it to document.body.className
const themeRaw: string = localStorage.getItem('theme')!;
document.body.className = themeRaw;
return (
<div className="App">
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="/contact" element={<h1>Hello contact</h1>} />
</Route>
</Routes>
</div>
);
}
export default App;
These above lines of code work as expected which is to store the theme and also change it. The theme is persistant but the icons are not and revert when refreshed.
But there is the issue that the icon when refreshed changes so I tried implementing this
index.js
import React, {useState} from 'react'
import { FaRegMoon, FaRegSun } from "react-icons/fa"
import "./index.scss"
const ThemeToggle = () => {
const icon_size = 30;
const [icon, setIcon] = useState('FaRegSun')
//const [icon] = useState('FaRegSun')
const changeTheme = (a) => {
const item = localStorage.getItem("theme")
let theme;
if (item === "dark") {
theme = "";
localStorage.setItem('theme', "")
} else {
theme = "dark"
localStorage.setItem('theme', 'dark')
}
//I think this is where the error is
const item2 = localStorage.getItem("iconName")
let iconName = a;
//
if (item2 === "FaRegSun") {
iconName = "FaRegMoon"
localStorage.setItem('iconName', "FaRegMoon")
} else {
iconName = "FaRegSun"
localStorage.setItem('iconName', "FaRegSun")
}
localStorage.setItem('theme', theme);
document.body.className = localStorage.getItem("theme");
localStorage.setItem('iconName', iconName);
document.body.className = localStorage.getItem("iconName");
setIcon(a);
}
const themeIsLight = (icon === 'FaRegMoon')
const Icon = themeIsLight ? <FaRegSun size={icon_size} onClick={() => changeTheme('FaRegSun') }/> : <FaRegMoon size={icon_size} onClick={() => changeTheme('FaRegMoon') }/>
return (
<div className="icon">
{Icon}
</div>
)
}
export default ThemeToggle;
and this was the updated App.tsx
import React from 'react';
import './App.sass';
import { Routes, Route } from 'react-router-dom';
import Layout from './components/Layout';
import Home from './components/Home';
function App() {
// makes the theme persist by getting the item theme from local storage
// converting to string and assigning it to document.body.className
const themeRaw: string = localStorage.getItem('theme')!;
document.body.className = themeRaw;
const iconRaw: string = localStorage.getItem('iconName')!;
document.body.className = iconRaw;
// setIcon(iconName)
return (
<div className="App">
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="/contact" element={<h1>Hello contact</h1>} />
</Route>
</Routes>
</div>
);
}
export default App;
These above lines do not work as expected as the local storage changes but there is no theme change or icon persistance
This is my css file if you are wondering that is used for the dark mode and light mode:
/*
bg: #d5d6db
fg: #343b58
red: #8c4351
orange: #965027
yellow: #8f5e15
green: #485e30
purple: #5a4a78
blue: #0f4b6e
*/
body {
--bg: #d5d6db;
--fg: #343b58;
--red: #8c4351;
--orange: #965027;
--yellow: #8f5e15;
--green: #485e30;
--purple: #5a4a78;
--blue: #0f4b6e;
}
body.dark {
--bg: #1a1b26;
--fg: #a9b1d6;
--red: #f7768e;
--orange: #ff9e64;
--yellow: #e0af68;
--green: #9ece6a;
--purple: #bb9af7;
--blue: #7dcfff;
}
/*
bg: #1a1b26
fg: #a9b1d6
red: #f7768e
orange: #ff9e64
yellow: #e0af68
green: #9ece6a
purple: #bb9af7
blue: #7dcfff
*/
What I checked:
Although the icon changed, the color scheme did not, so I checked local storage and found out that the icon and colorscheme are changing, and when I refreshed the local storage does keep it persistant and is the same but the icon reverts back and the colorscheme does not change in the first place.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
