React中setState修改video组件视频源不生效问题
React修改视频源后未切换问题修复
问题复现
需求为视频播放1秒后自动切换到另一个视频,通过state存储视频资源路径,延时调用setState更新路径后,video组件未切换播放内容,原实现代码如下:
import idle from './video/idle.mp4' import intro from './video/Intro.mp4' constructor(){ super() this.state= { vid: intro } } componentDidMount(){ setTimeout (()=> {this.setState ({ vid: idle } )}, 1000) ; } render() { return ( <div class="grid-container"> <div class="grid-item item2"> <video autoPlay={true} loop muted style={{width:"330px", height:"780px", paddingLeft:"10px", paddingTop:"220px"}}> <source src={this.state.vid} type="video/mp4"/></video> ); } }
问题根因
- 原生
<video>元素仅在首次挂载时读取内部<source>标签的src地址,后续单独修改<source>的src属性,不会触发video重新加载资源,自然不会切换视频 - 原代码存在基础语法错误:React中DOM类名属性需使用
className,不能直接写原生的class;render返回的DOM结构嵌套不完整,会直接导致编译/运行报错
修复方案
方案1:给video标签绑定key属性(实现成本最低)
将state中存储的视频路径作为key值传给video元素,当vid变化时,React会判定为元素更新类型为替换,直接卸载旧video元素、重新挂载新的video元素,自动加载新视频资源。
方案2:通过ref手动触发视频加载
给video元素绑定ref,在state的vid更新后,手动调用video元素的load()方法加载新资源,再调用play()方法触发播放。
修复后的可运行代码(采用方案1实现):
import idle from './video/idle.mp4' import intro from './video/Intro.mp4' constructor(){ super() this.state= { vid: intro } } componentDidMount(){ setTimeout(() => { this.setState({ vid: idle }) }, 1000); } render() { return ( <div className="grid-container"> <div className="grid-item item2"> <video key={this.state.vid} autoPlay loop muted style={{width:"330px", height:"780px", paddingLeft:"10px", paddingTop:"220px"}} src={this.state.vid} /> </div> </div> ); }
优化点:直接将src属性绑定在video标签上,不需要额外嵌套source标签,实现效果完全一致。
内容的提问来源于stack exchange,提问作者Anto-oh
相关产品推荐
相关产品推荐

