问题
I am trying to build a mini 2-track audio player with React. The audio is centrally controlled by a html audio element with a track-list inside a child component. The (yet to be styled) player can be seen here.
I can tell in the React dev tools that clicking the individual track select buttons does update the src of the audio element (thanks to the help of a member on here), however, the playing audio doesn't change. I've posted the Application code below.
Is it even possible to change the playing audio by updating the state in this way? Help would be hugely appreciated.
var TRACKLIST = [
{
id: 1,
name: "song a",
source: "./audio/test.m4a"
},
{
id: 2,
name: "song b",
source: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/557257/wwy.mp3"
}
]
function Track(props) {
return (
<div className="track">
<div className="meta">
<div className="name">
<h2>{props.name}</h2>
</div>
<audio>
<source src={props.source} />
</audio>
</div>
<button className="select" onClick={function() {props.onChange(props.source);}} >
</button>
</div>
)
}
var Application = React.createClass({
getInitialState: function() {
return {
isPlaying: "./audio/test.m4a"
};
},
onTrackChange: function(source) {
this.setState({ isPlaying: source })
},
render: function() {
return (
<div className="player">
<div className="tracklist">
{this.props.tracklist.map(function(track){
return <Track
key={track.id}
name={track.name}
source={track.source}
onChange={this.onTrackChange} />
}.bind(this))}
</div>
<div className="controls">
<audio controls>
<source src={this.state.isPlaying} />
</audio>
</div>
</div>
)
}
});
// Render the UI
ReactDOM.render(
<Application tracklist={TRACKLIST} />,
document.getElementById('Player')
);
回答1:
Audio files cannot be changed by just changing the src
like an image as there is caching. You will need to load
it and play
it again.
onTrackChange: function(source) {
this.setState({ isPlaying: source },function(){
this.refs.audio.pause();
this.refs.audio.load();
this.refs.audio.play();
})
}
The callback handles the pausing, loading and playing after the state has been changed. Remember to add a ref
to the audio tag.
<audio controls ref="audio">
<source src={this.state.isPlaying} />
</audio>
回答2:
Using Hooks
import useRef and create a instance of it.
import React, { useRef } from 'react';
const audioRef = useRef()
Function to update song.
const updateSong = (source) => {
setSource(source);
if(audioRef.current){
audioRef.current.pause();
audioRef.current.load();
audioRef.current.play();
}
}
Don't forget to add ref to audio tag.
<audio controls ref={audioRef}>
<source src={source} type='audio/mpeg' />
</audio>
来源:https://stackoverflow.com/questions/43577182/react-js-audio-src-is-updating-on-setstate-but-the-audio-playing-doesnt-chang