I have a component with a checkbox in it and for some reason it’s not firing. When I say firing I mean it does not console log or print out in the DOM. Nothing. I have tried onClick/onChange. Then I thought maybe this specific checkbox has a problem. But in the whole app no checkbox is firing. So maybe I am doing something wrong. Yes I have tried ChatGPT and checked elsewhere. Nothing works. Also restarted dev server.
import { useState } from "react";
export default function ThemeSwitcher() {
const [checked, setChecked] = useState(false);
const handleChange = () => {
setChecked((prevCheck) => !prevCheck);
};
console.log(checked);
return (
<div>
<label className="theme-switcher" htmlFor="themeswitch">
<div className="background"></div>
<input
type="checkbox"
id="themeswitch"
defaultChecked={checked}
onClick={() => handleChange()}
/>
<div className="switch" >
<img alt="theme switch to dark" className="moon" src="/moon.png"></img>
<img alt="theme switch to light" className="sun" src="/sun.png"></img>
</div>
</label>
</div>
);
}
2
Answers
If you want to log the updated value of a
useState
change, then you can call it inside of auseEffect
callback.This is because, were you to call the
console.log
from inside thehandleChange
function, you would see the old value of the state, asuseState
doesn’t execute the state update immediately. By using auseEffect
callback, you can place the state in the dependency array and cause an updated value to be logged on every change to that state. Like this:This would cause a value to be logged after every update to checked by the
handleChange
function.Apologies if I have misunderstood your requirements.
Several things going on.
You should use
checked
instead of defaultChecked if you want the input to be controlled by state (this is for clarity and correctness, but won’t really solve your immediate problem). It will solve the confusion, though, about why your checkbox appears to change state without your component re-rendering.Also, you should be using
onChange
instead ofonClick
. The most likely problem is that you prevented your input from receiving anonClick
due to CSS.onChange
wouldn’t suffer from this problem.