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

使用Material UI渲染axios获取的数据时图片无法显示问题求助

问题根因

  1. forEach 不支持异步等待,你在 forEach 中发起的批量获取相册照片的请求都是异步执行的,执行 setAlbums(tempArr) 时这些请求还没有返回结果,所以此时存入state的数组元素并没有photos属性。你在控制台看到的带photos的数组是因为控制台打印的是对象引用,等你手动点开查看时异步请求已经执行完成,才会显示完整数据,这是前端调试时的常见误区。
  2. useEffect 直接传入async函数属于错误用法,React会把async函数返回的Promise当成清理函数,可能引发额外的问题。
  3. 冗余操作:let tempArr = JSON.parse(JSON.stringify(res)).data 完全没有必要,axios会自动将接口返回的JSON数据解析为JS对象,直接取res.data即可,多余的序列化反序列化只会带来性能损耗。

修复方案

用Promise.all等待所有照片请求完成后再更新state,修改后的useEffect逻辑如下:

useEffect(() => {
  // 异步逻辑封装在内部函数中,不要直接给useEffect传async回调
  const fetchAlbums = async () => {
    const res = await axios.get(`https://jsonplaceholder.typicode.com/albums?userId=2`);
    const tempArr = res.data;
    // 用Promise.all等待所有相册的照片请求全部完成
    const albumWithPhotos = await Promise.all(
      tempArr.map(async (album) => {
        const photoRes = await axios.get(`https://jsonplaceholder.typicode.com/albums/${album.id}/photos`);
        return {
          ...album,
          photos: photoRes.data
        }
      })
    )
    // 所有数据准备完成后再更新state
    setAlbums(albumWithPhotos);
  }
  fetchAlbums();
}, []);

渲染逻辑优化

建议使用可选链做防御性判断,避免嵌套属性读取时报错:

{item?.photos?.length && 
  <ButtonBase sx={{ width: 128, height: 128 }}>
    <Img alt="complex" src={item.photos[0].thumbnailUrl} />
  </ButtonBase>
}

如果需要访问item.photos[0].thumbnailUrl做其他逻辑,也可以写成item?.photos?.[0]?.thumbnailUrl,哪怕中间某一层属性不存在也不会抛出报错,只会返回undefined。

内容的提问来源于stack exchange,提问作者vimuth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 13:24:04