使用React Context开发相册模态框 如何避免未赋值前的undefined报错
问题根因
- 模态框未打开时也在执行内部img标签的渲染逻辑,此时
clickedImg初始为空字符串,clickedImg.id为undefined,slideIndex初始值无效,访问albums[undefined]必然返回undefined,读取url属性就会抛出类型错误 - 你写的三元校验仅判断了
albums是否存在,未校验albums[slideIndex]是否存在,即使albums有值,索引无效时仍会读到undefined albums初始值为undefined,异步请求返回前访问albums.length等属性也会有潜在报错风险slideIndex仅在组件初始化时读取一次clickedImg.id,后续点击其他图片更新clickedImg时,slideIndex不会同步更新,会出现点击图片后模态框展示内容不匹配的问题- 你直接使用接口返回的图片id作为数组索引,而jsonplaceholder返回的图片id从1开始,数组索引从0开始,会出现索引错位问题
修复方案
1. 修正上下文初始值
修改AlbumContext中的状态初始值,避免空值报错:
// 原来的const [albums, setAlbums] = useState(); 改为 const [albums, setAlbums] = useState([]); // 原来的const [clickedImg, setClickedImg] = useState(""); 改为 const [clickedImg, setClickedImg] = useState(null);
2. 模态框仅打开时渲染内部内容
在Album组件的模态框部分增加短路判断,模态框关闭时不执行内部渲染逻辑:
<div className={modal ? "modal open" : "modal"}> {/* 仅模态框打开、有点击的图片、相册有数据时才渲染滑块内容 */} {modal && clickedImg && albums.length > 0 && ( <div> {/* 增加可选链校验,避免索引无效时报错 */} <img src={albums[slideIndex]?.url || ''} alt="" /> <button className="carousel-close-btn" onClick={handleOnclick}> close modal </button> <BtnSlider moveSlide={nextSlide} direction={"next"} /> <BtnSlider moveSlide={prevSlide} direction={"prev"} /> </div> )} </div>
3. 同步slideIndex和clickedImg
增加useEffect监听点击图片的变化,同步更新滑块索引,同时修正索引错位问题:
const [slideIndex, setSlideIndex] = useState(0); // 监听点击图片变化,更新滑块索引 useEffect(() => { if(clickedImg) { // 接口返回的id从1开始,数组索引从0开始,所以减1 setSlideIndex(clickedImg.id - 1); } }, [clickedImg])
4. 修正翻页逻辑适配数组索引
const nextSlide = () => { if (slideIndex < albums.length - 1) { setSlideIndex(slideIndex + 1); } else { // 最后一张切到第一张 setSlideIndex(0); } }; const prevSlide = () => { if (slideIndex > 0) { setSlideIndex(slideIndex - 1); } else { // 第一张切到最后一张 setSlideIndex(albums.length - 1); } };
内容的提问来源于stack exchange,提问作者notADevYet
相关产品推荐
相关产品推荐

