I'm new to React and I wish building a portfolio website. I need an image to be changed when a button is being toggled to lightMode (this button is in another component called Switcher). I'm using tailwind so when the button is toggled the html DOMelement's classlist is set to "dark", and reset to ""(empty string) when toggling back... Inside a a component called "Home" the image should switch every time the button is clicked. So to get it switching I'm testing if classlist of html DOMelement contains "dark" like so:
Home.js
import React, {useEffect, useRef, useState} from 'react';
import {AiFillGithub} from "react-icons/ai";
import {SiFacebook, SiCodepen, SiLinkedin} from "react-icons/si";
import darkImg from "../images/bg.jpg";
import lightImg from "../images/bg-light.jpg";
function Home(props) {
const html = document.querySelector("html");
const [imgg, setImgg] = useState(<img className="ml-14" src={darkImg} alt="home"/>);
useEffect(() => {
if (html.classList.contains("dark")){
setImgg(<img className="ml-14" src={lightImg} alt="home"/>);
}
else {
setImgg(<img className="ml-14" src={darkImg} alt="home"/>);
}
})
return (
<div className="h-full mt-[2px] flex-row">
<Img path={imgg}/>
<div className="font-arvo tracking-wider text-center text-7xl">PORTFOLIO</div>
<div className="text-center text-4xl">Software Engineer</div>
<div className="flex flex-row items-center justify-center mt-5 space-x-7">
<a href="#"><AiFillGithub className="social-icons" size="30"/></a>
<a href="#"><SiFacebook className="social-icons" size="30"/></a>
<a href="#"><SiCodepen className="social-icons" size="30"/></a>
<a href="#"><SiLinkedin className="social-icons" size="30"/></a>
</div>
</div>
);
}
const Img = (props) => {
return props.path;
}
export default Home;
Switcher.js
import React, {useEffect, useRef, useState} from 'react';
import {HiLightBulb} from "react-icons/hi";
import {MdDarkMode} from "react-icons/md";
function Switcher(props) {
const [foo, setFoo] = useState(
{
decor: "flex flex-row w-6 h-6 md:w-7 md:h-7 relative rounded-full transition duration-500 transform bg-two -translate-x-2 pt-1 pl-0.5 text-black",
icon: <MdDarkMode size="20"/>
}
);
const [isDark, setIsDark] = useState(true);
let Style1 = "flex flex-row w-6 h-6 md:w-7 md:h-7 relative rounded-full transition duration-500 transform bg-two -translate-x-2 pt-1 pl-0.5 text-black dark:bg-nine dark:text-seven";
let Style2 = "flex flex-row w-6 h-6 md:w-7 md:h-7 relative rounded-full transition duration-500 transform bg-two translate-x-full pt-1 pl-0.5 text-black dark:bg-nine dark:text-seven";
let icon1 = <MdDarkMode size="20"/>;
let icon2 = <HiLightBulb size="20"/>;
const html = document.querySelector("html");
function switchTheme() {
setIsDark(!isDark);
if(!isDark){
html.classList.add("dark");
setFoo({decor: Style2, icon: icon2});
}else{
html.classList.remove("dark");
setFoo({decor: Style1, icon: icon1});
}
}
return (
<Toggler decor={foo.decor} icon={foo.icon} onToggle={switchTheme}/>
);
}
const Toggler = (props) => {
return (
<button onClick={props.onToggle} className="absolute top-9 right-10 w-14 h-5 rounded-2xl flex items-center transition duration-300 focus:outline-none shadow bg-four dark:bg-white">
<div id="switch-toggle" className={props.decor}>
{props.icon}
</div>
</button>
);
};
export default Switcher;
On the browser's console I got this warning saying :
Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render. at Home (http://localhost:3000/main.428ce48dfed5fa0fec8a.hot-update.js:38:74) at div at App
I can see the image switching on Toggle but i don't think it's a clean use of hooks in Home.js Can Somebody provide any ideas... Thanks.