phantom phantom - 2 months ago 10
Javascript Question

How to structure component when using new Audio in react

I am new to React so getting to grip with thinking in React.

I want to play an audio clip when a user clicks on a button in React. I want the know the best way to set up the

component
so that I have the audio in the correct method of the component.

In my 'app' have 3 songs, but I only want to create one instance of the Audio object.

In jQuery I would do something like this:

var songs = ['1.mp3', '2.mp3', '3.mp3'];
var i = 0;
var audio = new Audio();

$('.play').click(function(){
audio.src = songs[i];
audio.play();
});

$('.next').click(function(){
i++;
audio.src = songs[i];
audio.play();
});


Currently my react code looks like below. Perhaps I am using
componentDidMount
incorrectly? Do I need to set
state
somewhere? or does it need to be a
prop
?

var Player = React.createClass({

componentDidMount: function() {
var audio = new Audio();
audio.src = "test.mp3"
},

playSong: function() {
console.log(audio)
audio.play();
},

render: function(){
return(
<div className="footer">
<i onClick={this.playSong} className="play"></i>
<i className="pause"></i>
<i className="next-song"></i>
</div>
)
}
});

Answer

You could have a prop of audioSources and have that be an array of mp3 file names. You could then also have a state of activeAudioIndex on your Player component and when it first loads do something like:

// set audio as a property of component `this.audio` can be accessed anywhere in component
audio: new Audio(), 

getInitialState: function() { 
  return {
   activeAudioIndex: 0
  }
},

componentDidMount: function() {
  this.audio.src = this.props.audioSources[this.state.activeAudioIndex]
}

nextSong: function() {
  var nextSongIndex = this.state.activeAudioIndex + 1 
  this.audio.src = this.props.audioSources[nextSongIndex]
  this.setState({activeAudioIndex: nextSongIndex})
}

playSong: function() {
  this.audio.play()
}

and then when you are actually using this component can do

<Player audioSources={['1.mp3', '2.mp3', '3.mp3']} />