如何在单个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
相关产品推荐
相关产品推荐

