React路由跳转后特定API请求失败问题求助
React路由跳转后无法调用Tasty API获取数据
我用react-router-dom实现React项目路由,遇到组件无法从特定API获取数据的问题:
- RecipeApi组件能正常获取Tasty API的食谱列表,点击RecipeCard会通过路由跳转到RecipeItself组件
- RecipeItself需要根据路由参数
id获取对应食谱详情,但跳转后无法读取fetch响应 - 换成星战API(
https://swapi.dev/api/people/1)能正常获取数据,直接访问目标Tasty API也成功,仅路由跳转后失效
App组件
import Recipe from "./components/Recipe"; import RecipeItself from "./components/RecipeItself"; import { BrowserRouter, Routes, Route } from "react-router-dom"; function App() { return ( <BrowserRouter> <Routes> <Route path="/recipes" element={<Recipe />} /> <Route path="/recipes/:id" element={<RecipeItself />} /> </Routes> </BrowserRouter> ); } export default App;
RecipeApi组件
import React, { useEffect, useState } from "react"; import { Link } from "react-router-dom"; function RecipeCard(props) { return ( <Link to={`/recipes/${props.api.id}`}> <div className="recipe_card"> <div className="recipe_img" style={{ backgroundImage: `url(${props.api.thumbnail_url})` }} /> <h1>{props.api.name}</h1> </div> </Link> ); } function RecipeApi(props) { const searchedOne = props.search; const [api, setApi] = useState([]); const options = { method: "GET", headers: { "X-RapidAPI-Key": process.env.REACT_APP_RECIPE_API_KEY, "X-RapidAPI-Host": "tasty.p.rapidapi.com", }, }; useEffect(() => { fetch( `https://tasty.p.rapidapi.com/recipes/list?from=0&size=20&q=$${searchedOne}`, options ) .then((response) => response.json()) .then((response) => setApi([...response.results])) .catch((err) => console.error(err)); }, [searchedOne]); return ( <section className="recipe_api"> <h2 className="recepe_api_title">Here are the recipes for you!</h2> <div className="recipe_api_boxes"> {searchedOne.length > 0 && api.map((api) => <RecipeCard key={api.id} api={api} />)} </div> </section> ); } export default React.memo(RecipeApi);
有问题的RecipeItself组件
import React, { useEffect, useState } from "react"; import { useParams } from "react-router-dom"; export default function RecipeItself() { const { id } = useParams(); const [cont, setCont] = useState([]); const options = { method: "GET", headers: { "X-RapidAPI-Key": process.env.REACT_APP_RECIPE_API_KEY, "X-RapidAPI-Host": "tasty.p.rapidapi.com", }, }; useEffect(() => { fetch( "https://swapi.dev/api/people/1" // 原API无法正常工作,所以替换为星战API测试 // `https://tasty.p.rapidapi.com/recipes/get-more-info?id=${id}`, // options ) .then((response) => response.json()) .then((response) => setCont(response)) .catch((err) => console.error(err)); }, []); console.log(cont); return ( <div className="recipe_itself"> <> {/* 注释掉的渲染代码 */} </> </div> ); }
问题排查与解决方案
1. 修复useEffect依赖缺失
RecipeItself组件的useEffect依赖数组为空,导致组件挂载时仅执行一次,此时路由参数id可能还未被正确解析。将id加入依赖数组,确保id变化时重新发起请求:
useEffect(() => { if (!id) return; // 确保id存在再发起请求 fetch( `https://tasty.p.rapidapi.com/recipes/get-more-info?id=${id}`, options ) .then((response) => { if (!response.ok) throw new Error(`HTTP错误!状态码: ${response.status}`); return response.json(); }) .then((response) => setCont(response)) .catch((err) => console.error(err)); }, [id]); // 加入id作为依赖项
2. 验证API权限与参数
- 在RecipeItself组件内打印
process.env.REACT_APP_RECIPE_API_KEY,确认环境变量是否正确加载 - 检查Tasty API的
get-more-info端点权限,确认当前API_KEY是否有权访问该接口 - 拼接完整请求URL(携带正确headers)在浏览器中直接测试,验证接口返回是否正常
3. 完善错误处理逻辑
原代码未检查HTTP响应状态,即使API返回4xx/5xx错误仍尝试解析JSON,导致报错。添加状态检查可快速定位问题:
.then((response) => { if (!response.ok) { console.log('API响应状态:', response.status); throw new Error(`请求失败: ${response.statusText}`); } return response.json(); })
4. 排查跨域问题
在浏览器开发者工具的Network面板查看请求的CORS响应头,确认是否存在跨域限制。若为CORS问题,需在后端配置代理,或使用RapidAPI提供的代理方案。
内容的提问来源于stack exchange,提问作者Jara
相关产品推荐
相关产品推荐

