I have a React component that plays/pauses audio when you click on a button. It works great and I render about 5 of these on a page at once. However, if you click play on one, and then click play on another, both audio's are playing, which isn't great. Here's my code for the component:
import React from 'react';
import playIcon from './images/play.png';
import pauseIcon from './images/pause.png';
class Music extends React.Component {
constructor(props) {
super(props);
this.state = { 'play': false };
this.url = props.src;
this.audio = new Audio(this.url);
this.audio.preload = 'none';
this.togglePlay = this.togglePlay.bind(this);
}
togglePlay() {
this.setState({'play': !this.state.play}, () => {
this.state.play ? this.audio.play() : this.audio.pause();
});
}
componentWillUnmount () {
this.audio.pause();
}
render() {
return (
<div style={this.props.style} className={this.props.className}>
{this.state.play
? <button className="audio-button" aria-label="Pause" onClick={this.togglePlay}><img src={pauseIcon} width="34" height="34" alt="Pause"></img></button>
: <button className="audio-button" aria-label="Play" onClick={this.togglePlay}><img src={playIcon} width="34" height="34" alt="Play"></img></button>}
</div>
);
}
}
export default Music;
I've done some looking around and a potential solution is to use redux or some other state management library. I'd like to avoid this as I otherwise have no need for that in this site. I've looked into event listeners (namely the solution proposed here) but when I do a document.getElementsByTagName('audio')
I get back an empty HTMLCollection
. This solution is closer, but I can't bridge the gap between it's implementation in jQuery to the one I'm using in React.
Is there a way to identify the playing audio and pause it from a React Component before playing new audio? Any and all suggestions are appreciated.