Reputation: 81
function MusicCard() {
const [playing, setPlaying] = useState(false);
const url = "http://localhost:4000/musics/myMusic.mp3";
const audio = new Audio(url);
const play = () => {
setPlaying(true);
audio.play();
};
const pause = () => {
setPlaying(false);
audio.pause();
};
return (
<div className="music-card">
<div className="music-card_image-con">
<button style={{
backgroundImage: `url(${process.env.PUBLIC_URL}music-image.jpg)`
}} onClick={playing ? pause : play}>{ playing ? <FaPause /> : <FaPlay /> }</button>
</div>
<div className="music-card_info-con">
<div className="music-card_info-name">
<h3>music name</h3>
<p> - </p>
<p>Singer</p>
</div>
<div className="music-card_info-seekbar">
<input type="range" style={{
width: "100%"
}} />
</div>
</div>
<button className="music-card_actions-btn"><FaEllipsisV /></button>
</div>
);
}
what is the problem with this toggle? when I press the play button it plays the music but when I pres it again it starts another session of the music like using another new Audio() method instead of pausing it!
Edit: the pause doesn't work and play starts new session of Audio every time starting to play
Upvotes: 1
Views: 3597
Reputation: 454
The setPlaying
call causes re-rendering and initializes a new instance of Audio
every time the component re-renders, you'll have to call useRef
to persist the Audio
instance between each render:
import { useState, useRef } from "react";
function MusicCard() {
const [playing, setPlaying] = useState(false);
const url = "http://localhost:4000/musics/myMusic.mp3";
const audioRef = useRef(new Audio(url));
const play = () => {
setPlaying(true);
audioRef.current.play();
};
const pause = () => {
setPlaying(false);
audioRef.current.pause();
};
return (
<div className="music-card">
<div className="music-card_image-con">
<button
style={{
backgroundImage: `url(${process.env.PUBLIC_URL}music-image.jpg)`,
}}
onClick={playing ? pause : play}
>
{playing ? <FaPause /> : <FaPlay />}
</button>
</div>
<div className="music-card_info-con">
<div className="music-card_info-name">
<h3>music name</h3>
<p> - </p>
<p>Singer</p>
</div>
<div className="music-card_info-seekbar">
<input
type="range"
style={{
width: "100%",
}}
/>
</div>
</div>
<button className="music-card_actions-btn">
<FaEllipsisV />
</button>
</div>
);
}
export default MusicCard;
Upvotes: 2