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

如何在单个React组件中实现多API调用并解决数据渲染问题

问题分析与解决方案

核心问题:Similar数据无法渲染的原因

你调用的Spoonacular /similar API接口返回的是食谱数组,但你的代码存在两个关键问题:

  • 把similar的初始状态设为了空对象{},和接口返回的数组结构不匹配
  • 渲染时直接尝试读取similar.title,这显然不符合数组的取值逻辑,自然拿不到数据

修复步骤

1. 修正状态初始化

将similar的初始状态改为空数组,匹配接口返回结构:

const [similar, setSimilar] = useState([]);

2. 正确渲染Similar数据

因为返回的是数组,需要用map循环渲染,同时处理加载状态避免报错:

<div>
  <h3>相似食谱</h3>
  {similar.length > 0 ? (
    <ul>
      {similar.map(recipe => (
        <li key={recipe.id}>{recipe.title}</li>
      ))}
    </ul>
  ) : (
    <p>加载中...</p>
  )}
</div>

3. 补充异常处理(可选但推荐)

API请求可能因网络或接口问题失败,给fetch函数加上try/catch避免页面崩溃:

const fetchDetails = async () => {
  try {
    const data = await fetch(`https://api.spoonacular.com/recipes/${params.name}/information?apiKey=${process.env.REACT_APP_API_KEY}`);
    const detailData = await data.json();
    setDetails(detailData);
  } catch (err) {
    console.error('获取详情失败:', err);
  }
};

const fetchSimilar = async () => {
  try {
    const data = await fetch(`https://api.spoonacular.com/recipes/${params.name}/similar?apiKey=${process.env.REACT_APP_API_KEY}`);
    const similarData = await data.json();
    setSimilar(similarData);
  } catch (err) {
    console.error('获取相似食谱失败:', err);
  }
};

是否需要合并API调用?

分开两个函数发起请求完全没问题,但合并成一个函数用Promise.all并行发起请求会更高效(两个请求同时进行,减少总等待时间),示例代码如下:

const fetchAllData = async () => {
  try {
    // 并行发起两个请求
    const [detailResponse, similarResponse] = await Promise.all([
      fetch(`https://api.spoonacular.com/recipes/${params.name}/information?apiKey=${process.env.REACT_APP_API_KEY}`),
      fetch(`https://api.spoonacular.com/recipes/${params.name}/similar?apiKey=${process.env.REACT_APP_API_KEY}`)
    ]);

    const detailData = await detailResponse.json();
    const similarData = await similarResponse.json();

    setDetails(detailData);
    setSimilar(similarData);
  } catch (err) {
    console.error('数据请求失败:', err);
  }
};

useEffect(() => {
  fetchAllData();
}, [params.name]);

额外优化:避免渲染时的报错

对于details的extendedIngredients,可以用可选链操作符避免数据未加载时的map报错:

{details.extendedIngredients?.map((ingredient) => (
  <li key={ingredient.id}>{ingredient.original}</li>
))}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:07:54