I have a React component that toggles a boolean when a button is clicked. It also successfully console logs the correct message when the button is clicked. But, it does not change the h2 element being returned. Why does this happen and how can I fix it? I research so far only brings up situations regarding state. Thank you.
function Heading() {
let darkModeOn = false;
const darkMode = <h2>Dark mode is on.</h2>;
const lightMode = <h2>Light mode is on.</h2>;
const handleMode = () => {
darkModeOn = !darkModeOn;
if (darkModeOn) {
console.log("Darkmode is on.");
} else {
console.log("Lightmode is on.");
}
};
return (
<div>
{darkModeOn ? darkMode : lightMode}
<button onClick={handleMode}>Click me</button>
</div>
);
}
export default Heading;
/// Updated code with the below that uses useState hook
import { useState } from "react";
const Mode = () => {
const [darkModeOn, setDarkMode] = useState(false);
let mode = "";
const handleMode = () => {
console.log("button clicked...");
setDarkMode(!darkModeOn);
if (darkModeOn) {
mode = "Dark mode";
} else {
mode = "Light mode";
}
};
return (
<>
<h2>{mode} is on.</h2>
<button onClick={handleMode}>Click to change mode.</button>
</>
);
};
export default Mode;
3
Answers
Please do it like the below:
You should use
useState
to force rerender the component with the new state.the way you did doesn’t trigger the component rerender.
More info:
https://beta.reactjs.org/reference/react/useState#ive-updated-the-state-but-logging-gives-me-the-old-value
Try this:
Or, you can also use the following code, where
mode
is also a state variable.I can see two issues in the code.
The first :
You are expecting
darkModeOn
to be updated immediately aftersetDarkMode(!darkModeOn)
so just after this line you do this :but, again, this is not how react works, when you run a code to update a state, only when this code finishes execting the component rerenders and only then, the state will be updated, so at the moment the
if
statement is executed the new value ofdarkModeOn
is not available yet (because the component didn’t rerendered yet).The second:
As it is said, when you updae a state like you are doing inside the
handleMode
function the component rerenders and in this new rendermode
will be initilized again to''
so doing so is really useless, you don’t even need thismode
variable.You can simply display inside your JSX based on the value of
darkModeOn