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

