You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 06:06:19