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

React JS中视频上传前预览功能重复上传异常问题求助

解决视频预览重复上传不更新的问题

我来帮你搞定这个视频预览的问题!你遇到的核心问题是第二次上传新视频时,旧视频还在播放、新预览不显示,主要有几个关键调整点:

1. 修复File Input的受控值错误

你当前给input的value设置为formik.values.video.name,但formik.values.video是你通过setFieldValue存入的文件数组(myFiles = Array.from(files)),数组本身没有name属性,这会导致input的value变成undefined,浏览器可能因此认为文件没有变化,进而阻止新的文件选择逻辑正常触发。

解决方案:
要么直接去掉input的value属性(让它变成非受控组件,更适合文件上传场景),要么正确绑定第一个选中文件的名称:

<input 
  type="file" 
  id="videos" 
  accept="video/*" 
  className="text-transparent -ml-52" 
  onChange={(e) => {
    // 原有逻辑...
  }} 
  // 正确绑定第一个选中文件的名称,或者直接去掉这个value属性
  value={formik.values.video?.[0]?.name || ''}
/>

2. 强制Video元素刷新预览

即使videoPreview状态更新了,<source>标签的src变化可能不会触发video元素自动加载新内容——React更新子元素时,video不会主动触发load事件。这里有两个简单的解决办法:

方法A:直接给video标签绑定src

把videoPreview直接赋值给video元素的src属性,而不是用<source>子标签,这样状态更新时video会自动加载新数据源:

<video 
  width="400" 
  height="150" 
  style={{ height: "143px", objectFit: "contain" }} 
  autoPlay 
  loop
  src={videoPreview}
/>

方法B:给video加key属性强制重渲染

给video元素添加key={videoPreview},每次videoPreview更新时,React会销毁旧的video组件并创建新的,自然会加载新视频:

<video 
  width="400" 
  height="150" 
  style={{ height: "143px", objectFit: "contain" }} 
  autoPlay 
  loop
  key={videoPreview}
>
  <source src={videoPreview} />
</video>

3. 验证State更新是否生效

为了确认videoPreview状态确实在更新,可以添加日志监听:

// 在组件里添加useEffect监听状态变化
import { useEffect } from 'react';

useEffect(() => {
  console.log('当前视频预览地址:', videoPreview);
}, [videoPreview]);

// 同时在FileReader的onload里加日志
fileReader.onload = () => {
  if (fileReader.readyState === 2) {
    console.log('新视频的DataURL:', fileReader.result);
    formik.setFieldValue("video", myFiles);
    setVideoPreview(fileReader.result);
  }
};

如果日志显示videoPreview确实更新了,但预览还是没变化,那问题就出在video元素没有刷新,用上面的方法B就能解决。

4. 额外优化:停止旧视频播放

在选择新视频时,先暂停旧视频的播放,避免新旧视频同时播放的尴尬:

onChange={(e) => {
  // 暂停旧视频(给video加id更可靠)
  const videoEl = document.getElementById('preview-video');
  if (videoEl) videoEl.pause();

  // 原有文件处理逻辑...
  const files = e.target.files;
  let myFiles = Array.from(files);
  const fileReader = new FileReader();
  fileReader.onload = () => {
    if (fileReader.readyState === 2) {
      formik.setFieldValue("video", myFiles);
      setVideoPreview(fileReader.result);
    }
  };
  if (e.target.files[0]) {
    fileReader.readAsDataURL(e.target.files[0]);
  }
}}

记得给video标签加上id:id="preview-video"

按照上面的步骤调整后,重复上传视频时预览应该就能正常更新了!

内容的提问来源于stack exchange,提问作者Ali Raza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 12:02:38