I have a function that does some animation using async await()
. I want to play/pause the animation onClick
. I used useState
to update the variable but the function is not behaving as I want. While the const print ()
is running and when I click on the button, text updates, but the function doesn't break. In the log, "play" is printed 100 times. I'm guessing useState
and async
is causing something. How can I solve this?
const Test= props => {
const [ButtonText, SetButtonText] = useState("Play");
const ToggleButtonText = () => {
if(ButtonText == "Play")
SetButtonText("Pause")
if(ButtonText == "Pause")
SetButtonText("Play")
}
const delay = ms => new Promise(res => setTimeout(res, ms));
const print= () => {
for(var i = 0; i < 100; i++)
{
///
work
await delay(1000);
work
///
console.log(ButtonText);
if(ButtonText == "Pause")
break ;
}
};
return (
<div>
<div>
///work component///
</div>
<button onClick = {() => ToggleButtonText()}> {ButtonText}</button>
</div>
)
}
The ButtonText
is declared as const
- it can't change its value inside a given call of the functional component.
Without more info, I'd use a ref as well as state, so that the loop can see if the ref gets changed:
const buttonTextRef = useRef();
// Update the ref to ButtonText every time ButtonText changes:
useEffect(() => {
buttonTextRef.current = ButtonText;
}, [ButtonText]);
if (buttonTextRef.current === 'Pause') {
break;
}
Another method would be to put the index being iterated over into state, and instead of looping 100 times, re-render 100 times, eg, something along the lines of:
const [printI, setPrintI] = useState(0);
if (printI) {
// Then we're in the middle of iterating
// work
if (printI < 100) {
setTimeout(() => {
setPrintI(printI + 1);
}, 1000);
} else {
setPrintI(0);
}
};
and to stop it, call setPrintI(0)
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.