如何通过useEffect立即使用API数据?React随机图片加载问题
解决方案
方案一:API请求完成后直接初始化随机图片
不需要拆分两个useEffect,在获取到图片数据后直接生成随机图并设置到memes数组,确保只执行一次,避免重复添加:
const [allImages, setAllImages] = useState([]); const [memes, setMemes] = useState([]); useEffect(() => { fetch("https://api.imgflip.com/get_memes") .then(response => response.json()) .then(data => { const imageList = data.data.memes; setAllImages(imageList); // 生成随机图并初始化memes if (imageList.length > 0) { const randomIdx = Math.floor(Math.random() * imageList.length); setMemes([{ img: imageList[randomIdx].url }]); } }); }, []);
方案二:结合可选链与条件渲染处理初始状态
如果希望memes初始就有结构,同时避免报错,可以用可选链处理空值,渲染时做条件判断:
const [allImages, setAllImages] = useState([]); // 初始给空字符串占位 const [memes, setMemes] = useState([{ img: "" }]); useEffect(() => { fetch("https://api.imgflip.com/get_memes") .then(response => response.json()) .then(data => { const imageList = data.data.memes; setAllImages(imageList); const randomIdx = Math.floor(Math.random() * imageList.length); // 更新memes中的图片 setMemes([{ img: imageList[randomIdx].url }]); }); }, []); // 渲染部分 return ( <div> {/* 有图片时显示,否则显示加载状态 */} {memes[0].img ? ( <img src={memes[0].img} alt="Random meme" /> ) : ( <p>Loading...</p> )} </div> );
为什么之前的方案会出现两张图片?
React严格模式下,useEffect可能会被执行两次(开发环境),加上你监听allImages的变化,当allImages被设置时,addImage会被调用多次,导致重复添加。方案一在API请求完成后只执行一次setMemes,就不会有这个问题。
内容的提问来源于stack exchange,提问作者malbo
相关产品推荐
相关产品推荐

