You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 06:03:37