问题代码片段:
<audio controls controlsList="nodownload" > <source src={this.state.voiceURL} type="audio/ogg" /> <track kind="captions" /> 您的浏览器不支持 audio 元素。 </audio>
问题描述:
原文链接:https://github.com/facebook/react/issues/9447
原文:The browser is not recognising any changes React makes to the src
prop of <source>
, if you change the src
prop directly on the <audio>
tag the browser re-renders/resets the audio tag as expected.
翻译:浏览器无法识别对<source>的src属性做出的任何更改,如果直接在<audio>标签上更改src属性,浏览器将按照预期重新渲染/重置音频标签。
所以我们需要对audio重新处理。一种方式是直接重新包装一个audio的组件,可以直接参考github上的资料。
另外一个是通过ref的方式去处理,通过ref直接获取audio对象,代码如下:
<audio ref={(audio) => { this.audioValue = audio; }} controls preload="none" controlsList="nodownload" > <track kind="captions" /> 您的浏览器不支持 audio 元素。 </audio>
然后在需要给这个audio对象赋值的地方执行如下代码:
theAudio = this.audioValue; theAudio.src = ''; theAudio.src = this.state.audioUrl; theAudio.load();
完整代码:(下面代码还处理了通过字段属性控制audio的显隐,熟悉react的生命周期,数据和对象操作的分离)
let theAudio = null; export default class Audio extends React.Component { constructor(props) { super(props); this.state = { audioUrl: null,//接口返回的音频地址 }; } componentWillReceiveProps(nextProps) { //通过接口获取音频地址 if (nextProps.getAudioUrl) { this.setState({ audioUrl: nextProps.getAudioUrl }); } else { this.setState({ audioUrl: null }); } } //这个周期在render后执行,此时你的audio对象是存在的 componentDidUpdate() { if (this.state.audioUrl) { theAudio = this.audioValue; theAudio.src = ''; theAudio.src = this.state.audioUrl; theAudio.load(); } } render(){ return ( { audioUrl&& <audio ref={(audio) => { this.audioValue = audio; }} controls preload="none" controlsList="nodownload" > <track kind="captions" /> 您的浏览器不支持 audio 元素。 </audio>}) } }