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

React组件中通过Axios与Hooks调用双API渲染猫数据及图片

在React中结合Hooks和Axios调用双API渲染猫咪数据与图片

我来帮你搞定这个需求!要把猫咪品种数据和对应图片一起渲染,我们可以通过封装API请求、批量获取图片、合并数据这几个步骤来调整现有代码,下面是具体实现方案:

第一步:优化API请求封装

先把API请求逻辑从组件中抽离出来,让代码更清晰易维护,修改你的mainApi.js:

// mainApi.js
import axios from 'axios';
export const baseUrl = 'https://api.thecatapi.com/v1/';

// 获取全量猫咪品种列表
export const fetchBreeds = async () => {
  const response = await axios.get(`${baseUrl}breeds`);
  return response.data;
};

// 根据品种ID获取对应猫咪图片(返回第一张图片的URL)
export const fetchCatImageByBreedId = async (breedId) => {
  const response = await axios.get(`${baseUrl}images/search?breed_id=${breedId}`);
  return response.data[0]?.url; // 用可选链避免无数据时报错
};

第二步:修改React组件,合并数据与图片

接下来调整CatsList.js,我们会先获取品种列表,再批量请求每个品种的图片,最后把图片URL和品种数据合并后渲染,同时增加加载、错误状态提升用户体验:

// CatsList.js
import React, { useState, useEffect } from 'react';
import { fetchBreeds, fetchCatImageByBreedId } from './services/mainApi';

export default function CatsList() {
  const [breedsWithImages, setBreedsWithImages] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [errorMsg, setErrorMsg] = useState(null);

  useEffect(() => {
    const loadCatData = async () => {
      try {
        setIsLoading(true);
        // 1. 获取所有猫咪品种数据
        const breedList = await fetchBreeds();
        
        // 2. 批量请求每个品种对应的图片,用Promise.all并行处理提升效率
        const mergedData = await Promise.all(
          breedList.map(async (breed) => {
            const imgUrl = await fetchCatImageByBreedId(breed.id);
            return { ...breed, imageUrl: imgUrl }; // 合并图片URL到品种对象
          })
        );

        setBreedsWithImages(mergedData);
      } catch (err) {
        setErrorMsg('加载猫咪数据失败,请稍后重试');
        console.error('请求出错:', err);
      } finally {
        setIsLoading(false); // 不管成功失败都结束加载状态
      }
    };

    loadCatData();
  }, []);

  // 处理加载/错误状态的UI
  if (isLoading) return <div className="loading">正在加载可爱猫咪...</div>;
  if (errorMsg) return <div className="error">{errorMsg}</div>;

  return (
    <ul className="row">
      {breedsWithImages.map((cat) => (
        <li className="col-md-3 list-item" key={cat.id}>
          <a 
            href={cat.wikipedia_url} 
            target="_blank" 
            rel="noopener noreferrer"
            style={{ textDecoration: 'none', color: 'inherit' }}
          >
            {/* 渲染猫咪图片,判断URL存在才显示 */}
            {cat.imageUrl && (
              <img 
                src={cat.imageUrl} 
                alt={`${cat.name} 猫咪`} 
                style={{ 
                  width: '100%', 
                  height: '220px', 
                  objectFit: 'cover',
                  borderRadius: '8px',
                  marginBottom: '12px'
                }}
              />
            )}
            <h3 style={{ margin: '0 0 8px' }}>{cat.name}</h3>
            <p style={{ margin: '0 0 8px', fontSize: '14px', color: '#666' }}>
              原产地:{cat.origin}
            </p>
            <p style={{ fontSize: '13px', lineHeight: '1.5' }}>
              {cat.description}
            </p>
          </a>
        </li>
      ))}
    </ul>
  );
}

关键细节说明

  • 并行请求优化:用Promise.all同时发起所有图片请求,比逐个串行请求节省大量等待时间
  • 错误处理:添加了错误捕获和状态提示,避免页面出现空白或崩溃
  • 安全跳转:给外部链接加上rel="noopener noreferrer",防止潜在的安全风险
  • 图片容错:用可选链?.和条件渲染处理图片请求失败的情况,避免无效图片占位

如果担心品种太多导致请求量过大,还可以考虑添加本地缓存(比如用localStorage存储已请求过的图片URL),或者查看TheCatAPI是否支持批量获取多个品种图片的接口,进一步优化请求次数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:22:39