React从全局state取单条视频数据 刷新/直接访问URL加载失败如何解决
问题根因
刷新/直接输入URL访问时触发问题的核心原因有3个:
- 异步请求时序冲突:页面刷新后全局
VideoContext会重置,全量视频的接口是异步发起的,单视频页挂载时接口还未返回数据,videos还是初始空数组,此时查找目标视频只会得到undefined - useEffect依赖缺失:单视频页查找视频的逻辑依赖
videos和路由参数slug,但你没有将这两个变量加入useEffect的依赖数组,后续videos加载完成后也不会重新触发匹配逻辑 - 状态初始化不合理:
video是单个视频对象,你初始设置为数组[],后续访问属性时不会立即报错,但逻辑不符合预期,容易引发渲染异常
修复方案
直接修改SingleVideo组件代码即可,修改点如下:
- 给useEffect添加
[videos, slug]依赖项 - 修改
video初始值为null,增加加载态/404判断,避免渲染报错 - 匹配视频时做非空判断,兼容数据未加载完成的场景
修正后的SingleVideo代码
import { useState, useEffect, useContext } from "react"; import { useParams } from "react-router-dom"; import { VideoContext } from "../context/videoContext"; const SingleVideo = () => { let { slug } = useParams(); const [videos] = useContext(VideoContext); // 初始值改为null,单个对象不需要用数组 const [video, setVideo] = useState(null); // 添加依赖项:videos和slug useEffect(() => { if (!videos.length) return; const result = videos.find(item => item.uuid === slug); setVideo(result); }, [videos, slug]); // 加载中提示 if (video === null) return <div>加载中...</div> // 未找到视频的404提示 if (!video) return <div>未找到对应视频</div> return ( <> <div> <h1>{video.title}</h1> <p>{video.content}</p> <img src={video.thumbnail} alt={video.title} /> </div> </> ); }; export default SingleVideo;
可选优化建议
如果全量视频数据量较大,也可以单独为单视频页新增后端接口,根据slug直接请求单条视频数据,不用依赖全局Context的全量数据,性能和稳定性会更好。
内容的提问来源于stack exchange,提问作者Darth Vader
相关产品推荐
相关产品推荐

