I have a small app that is playing some audios when I press play and stops when I press the button again using isPlaying state. The functionality of play/stop works good, but I want to add a progress bar to show the song's progress. I used useEffect and a "completed" state so that the progress bar will show the progress with css styling. everything works, except that I can't clear the interval. When I press stop, the song stops, but the progress bar continues, after checking I figured that clearInterval doesn't work. This is my useEffect function:
const ProgressBar = ({isPlaying}) => {
const [completed, setCompleted] = useState({
count: 0
});
useEffect(() => {
if (isPlaying){
setInterval(() => {
setCompleted(completed.count+=5.8)
if(completed.count > 99) {
setCompleted(completed.count=0);
}
}, 1000);
}
else {
clearInterval()
}
}, [isPlaying]);
I tried to add:
const intervalId = setInterval(() => { ...
and then pass the intervalId to clear(intervalId)
but then I need to add condition of - if (isPlaying) before that.
and when I do so, I can't use "else { clearInterval(intervalId)}
Because IntervalId is undefined under the else scope.
How can I pass that and clear the interval?
I tried multiple ways which didn't work for some reason. Any help would be appreciated!
Edited:
I tried to console log just to make sure the playing state get the change from the play/stop toggle, and it works ok:
useEffect(() => {
if (isPlaying) {
console.log("playing")
}
else {
console.log("not playing")
}
I have "ControlPanel" component, so I can't configure the ProgressBar component functionality with the buttons functionality:
const ControlPanel = ({
setIsLooping, isLooping, isPlaying, setIsPlaying}) => {
return (
<div>
<PlayButton>
{!isPlaying ? (
<button type="button"
className="play"
onClick={() => setIsPlaying(true)}>
<ImPlay2></ImPlay2> Play
</button>
) : (
<button type="button"
className="pause"
onClick={() => setIsPlaying(false)}>
<ImStop></ImStop> Stop
</button>
)}
</PlayButton>
<Flex> .....
use can store setInterval id in ref
const intervalId = useRef(null)
useEffect(() => {
if (isPlaying){
intervalId.current = setInterval(() => {
setCompleted(completed.count+=5.8)
if(completed.count > 99) {
setCompleted(completed.count=0);
}
}, 1000);
}
else {
clearInterval(intervalId.current)
}
// it's better to clean up your component
return () => {
clearInterval(intervalId.current)
}
}, [isPlaying]);