For some reason, whenever I use this in my React TS project, I need to press the button twice to change the text from "Goodbye" to "Hello" but not the other way around?
import { useState } from 'react'
const ChangeTextButton = () => {
const [buttonText, setButtonText] = useState("Click me!")
var changedBefore = false;
function changeText() {
if (changedBefore) {
setButtonText("Hello")
} else {
setButtonText("Goodbye")
}
changedBefore = !changedBefore
return buttonText;
}
return(
<button onClick={() => changeText()}>{buttonText}</button>
);
}
export default ChangeTextButton;
Yeah, I know this is bad code, I'm relatively new to TypeScript and JS as a whole.
CodePudding user response:
This happen because your changedBefore
variable will be set to false
after each rerender.
So it starts from false
, at the first click it change the text button to "Goodbye" and rerender. The rerender will put set the value back to false
again. The next click will change the text to "Goodbye" again, but since it's the same state as the actual one, it won't trigger a rerender so your changedBefore
will be true
for next click, that will finally change text to "Hello"
If you want to avoid this behavior you will have to use useState
or useRef
for your changedBefore
variable, like this:
import { useState } from 'react'
const ChangeTextButton = () => {
const [buttonText, setButtonText] = useState("Click me!")
const [changedBefore, setChangedBefore] = useState(false);
function changeText() {
if (changedBefore) {
setButtonText("Hello")
} else {
setButtonText("Goodbye")
}
setChangedBefore(cb => !cb)
}
return(
<button onClick={() => changeText()}>{buttonText}</button>
);
}
export default ChangeTextButton;
Demo: https://stackblitz.com/edit/react-wuulup?file=src/App.js