React中如何正确拼接数据库视频文件名至src以加载视频
问题解决方案
核心问题分析
- 路径错误:React项目中
public目录是静态资源的根访问目录,直接通过/uploads/文件名即可访问public/uploads下的文件,你写的/../uploads/会跳转到public的上级目录,导致找不到视频文件。 - 初始状态空值问题:组件初始时
course是空对象,course.video为undefined,拼接出的路径是/uploads/undefined,会导致视频加载失败;即使后续接口返回数据更新course,部分场景下video元素不会自动重新加载source。
修复步骤
1. 修正视频路径
将/../uploads/${course.video}改为/uploads/${course.video},直接指向public/uploads目录下的文件。
2. 处理初始状态与空值
- 将
course的初始状态设为null,避免空对象导致的属性读取问题 - 添加条件渲染,确保只有当
course和course.video存在时,才渲染视频元素
3. 验证数据一致性
确认数据库返回的course.video文件名,与public/uploads目录下的实际文件名完全一致(包括大小写、后缀名)。
修改后的完整代码
import axios from 'axios' import React, { useEffect, useRef, useState } from 'react' import { useParams } from 'react-router-dom' const CourseDetail = () => { const [course, setCourse] = useState(null) const [playing, setPlaying] = useState(false) const { id } = useParams() const videoRef = useRef(null) useEffect(() => { axios.get(`http://localhost:3001/lesson/${id}`) .then((response) => { setCourse(response.data[0]) }) }, [id]) const onVideoPress = () => { if (playing) { videoRef?.current?.pause() setPlaying(false) } else { videoRef?.current?.play() setPlaying(true) } } if (!course) { return <div className='w-8/12 bg-white mx-auto p-10 rounded-md shadow-md mt-10'>加载中...</div> } return ( <div className='w-8/12 bg-white mx-auto p-10 rounded-md shadow-md mt-10'> <h1 className='text-red-400 font-bold text-xl'>{course.title}</h1> <div className='w-8/12 bg-gray-900 mx-auto mt-10'> {course.video ? ( <video ref={videoRef} onClick={onVideoPress} className='w-1/2 mx-auto'> <source src={`/uploads/${course.video}`} type="video/mp4" /> </video> ) : ( <div className='text-white text-center py-10'>暂无视频资源</div> )} </div> </div> ) } export default CourseDetail
内容的提问来源于stack exchange,提问作者Shan Du
相关产品推荐
相关产品推荐

