React详情页无法渲染选中食谱数据问题求助
问题排查与修复方案
核心问题分析
你的页面空白但能正确跳转,大概率是数据未正确获取或参数传递错误导致的,以下是针对性的修复步骤:
1. 修复路由参数获取方式
你当前通过props.id接收参数,但React Router v6中路由参数需要用useParams钩子获取,这是最可能的根源:
// 导入useParams import { useParams } from 'react-router-dom'; const Details = () => { // 替换props.id为useParams获取路由参数 const { id } = useParams(); // ...其余代码 };
同时确保路由配置正确:
// 路由定义示例 <Route path="/details/:id" element={<Details />} />
2. 完善数据获取逻辑
- 添加
id到useEffect依赖数组,确保参数变化时重新请求 - 增加错误捕获与调试日志
- 处理加载状态避免空白页面
const [recipe, setRecipe] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { if (!id) return; setIsLoading(true); recipeService.getOne(id) .then(result => { console.log('API返回数据:', result); // 打印确认数据结构 setRecipe(result); setError(null); }) .catch(err => { console.error('请求失败:', err); setError('无法加载食谱信息'); }) .finally(() => { setIsLoading(false); }); }, [id]); // 添加id到依赖数组
3. 优化渲染逻辑
在数据加载完成前显示状态提示:
if (isLoading) { return <div>加载中...</div>; } if (error) { return <div>{error}</div>; } if (!recipe) { return <div>未找到对应食谱</div>; }
4. 修复useLayoutEffect冗余执行
当前useLayoutEffect会在每次渲染时触发滚动,添加空依赖数组让它仅执行一次:
useLayoutEffect(() => { window.scrollTo(0, 0); }, []); // 添加空依赖数组
完整修复后代码示例
import "./Details.css"; import { Link } from 'react-router-dom'; import { useParams } from 'react-router-dom'; import React, { useEffect, useLayoutEffect, useState } from 'react'; import * as recipeService from "../../../services/recipeService"; const Details = () => { const { id } = useParams(); const [recipe, setRecipe] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { if (!id) return; setIsLoading(true); recipeService.getOne(id) .then(result => { console.log('API响应:', result); setRecipe(result); setError(null); }) .catch(err => { console.error('请求错误:', err); setError('无法获取食谱信息'); setRecipe(null); }) .finally(() => { setIsLoading(false); }); }, [id]); useLayoutEffect(() => { window.scrollTo(0, 0); }, []); if (isLoading) { return <div>加载中...</div>; } if (error) { return <div>{error}</div>; } if (!recipe) { return <div>未找到对应的食谱</div>; } return ( <div> <section className="sec11"> <h1>{recipe.name}</h1> <article className="main"> <article className="artsm"> <h4>Ingredients</h4> <p>{recipe.ingredients}</p> </article> <article className="artm"> <img src={recipe.imageUrl} alt={recipe.name} /> <hr /> <h4>{recipe.name}</h4> <p>Cooking Time: {recipe.time}</p> <p className="cut-text">{recipe.instructions}</p> </article> <article className="artsm"> <h4>Instructions</h4> <p className="inst">{recipe.instructions}</p> </article> </article> <article className="comment"> <form className="form"> <textarea name="comment" placeholder=" Comment..."></textarea> <input className="btncom" type="submit" value="Comment" /> </form> </article> </section> <section className="sec5nav"> <ul> <li><Link to="/"><i className="fas fa-solid fa-book-bookmark"></i> Home</li> <li><Link to="/recipes"><i className="fas fa-thin fa-bowl-rice"></i> Recipes</li> <li><Link to="/personal-list"><i className="fas fa-solid fa-list-ul"></i> Your Recipes</li> <li><Link to="/favourites"><i className="fa-solid fa-heart"></i> Favourites</li> <li><Link to="/create-recipe"><i className="fas fa-solid fa-plus"></i> Add Recipe</li> <li><Link to="/user-profile"><i className="fas fa-solid fa-user"></i> Your Profile</li> </ul> <a href="#" className="to-top" id="to-top"> <i className="fas fa-chevron-up"></i> </a> </section> </div> ); }; export default Details;
内容的提问来源于stack exchange,提问作者DimitriTfb
相关产品推荐
相关产品推荐

