In the application, by clicking on the button, I want to do 2 things: play an audio file, show 2 pictures. After clicking the button again, I want to turn off the audio and hide 2 pictures. The audio works, but the pictures go crazy. Why? I set useState as "false" in default, but after loading pages they are "true". I do not understand why?
import {useEffect, useRef, useState} from "react";
import styled from "./Cat.module.scss";
import Swing from "../../assets/audio/GirlsLikeToSwing.mp3";
let dancingImg = ['https://i.gifer.com/P6XV.gif', 'https://i.gifer.com/DCy.gif']
const Cat = () => {
const [isPlaying, setIsPlaying] = useState(false);
const audioElement = useRef();
const [ladyDancing, setLadyDancing] = useState(false);
const [catDancing, setCatDancing] = useState(false);
const playPause = () => {
setIsPlaying(!isPlaying);
}
useEffect(() => {
if (isPlaying) {
audioElement.current.play();
setLadyDancing(ladyDancing);
setCatDancing(catDancing);
} else {
audioElement.current.pause();
setLadyDancing(!ladyDancing);
setCatDancing(!catDancing);
}
}, [isPlaying]);
return (<div className={styled.headerContainer}>
<div className={styled.lady}>
{ladyDancing ? <img src={dancingImg[0]} alt="" className={styled.ladyDancing}/> : null}
{catDancing ? <img src={dancingImg[1]} alt="" className={styled.catDancing}/> : null}
</div>
<button onClick={playPause}>Play</button>
<audio src={Swing} ref={audioElement}></audio>
</div>
)
};
export default Cat;
useEffect
runs during the first render and all subsequent updates.
I believe you might need to explicitly perform setLadyDancing to true or false depending on the state that you want them to be, otherwise it will keep getting toggled based on its previous state.
Maybe this might work:
useEffect(() => {
if (isPlaying) {
audioElement.current.play();
setLadyDancing(true);
setCatDancing(true);
} else {
audioElement.current.pause();
setLadyDancing(false);
setCatDancing(false);
}
}, [isPlaying]);