React中MenusShow.jsx组件Props数据不显示问题求助
问题分析与解决方案
核心问题
- 状态声明顺序违规:
useEffect钩子在menus状态声明前调用,违反React Hooks使用规则,可能引发状态更新异常。 - 直接访问详情页数据丢失:
currentMenu仅在从MenusIndex点击时赋值,若直接通过URL访问/menus/:menuId,currentMenu为空对象,导致MenusShow无数据可渲染。 - 页面刷新后数据重置:
currentMenu是内存状态,页面刷新后会清空,同样导致详情页显示异常。
修复步骤
1. 调整状态声明顺序
在 Content.jsx 中,将状态声明移至 useEffect 之前:
export function Content() { // 先声明状态 const [menus, setMenus] = useState([]); const [currentMenu, setCurrentMenu] = useState({}); // 再定义数据获取逻辑与钩子 const handleIndexMenus = () => { console.log("handleIndexMenus"); axios.get("http://localhost:3000/menus.json").then((response) => { console.log(response.data); setMenus(response.data); }); }; useEffect(handleIndexMenus, []); const handleShowMenu = (menu) => { console.log("handleShowMenu", menu); setCurrentMenu(menu); }; // ... 其余代码 }
2. 修改MenusShow数据获取逻辑(推荐方案)
让 MenusShow 直接根据 menuId 从 menus 数组筛选数据,摆脱对 currentMenu 的依赖,兼容所有访问方式:
更新Content.jsx路由
传递 menus 数组给 MenusShow:
<Route path="/menus/:menuId" element={<MenusShow menus={menus} />} />
重构MenusShow.jsx
import { useParams } from "react-router-dom"; export function MenusShow(props) { const { menuId } = useParams(); // 根据menuId匹配对应菜单 const menu = props.menus.find(item => item.id === menuId); console.log("MenusShow menuId:", menuId); console.log("MenusShow found menu:", menu); if (!menu || !menu.event || !menu.recipe) { console.log("No data available for menuId", menuId); return <div>No data available</div>; } const { event, recipe } = menu; return ( <div> <h3>{event.title}</h3> <h3>Recipes:</h3> <p>{recipe.title}</p> </div> ); }
3. 可选:保留currentMenu优化的兼容方案
若希望保留列表页点击时的 currentMenu 缓存,可在 Content.jsx 中添加路由监听逻辑,自动补全空状态:
import { useParams, useLocation } from "react-router-dom"; export function Content() { const [menus, setMenus] = useState([]); const [currentMenu, setCurrentMenu] = useState({}); const location = useLocation(); const { menuId } = useParams(); useEffect(() => { // 路由切换到详情页且currentMenu为空时,自动从menus中匹配数据 if (location.pathname.startsWith('/menus/') && menuId && Object.keys(currentMenu).length === 0) { const foundMenu = menus.find(item => item.id === menuId); if (foundMenu) setCurrentMenu(foundMenu); } }, [location, menuId, menus, currentMenu]); // ... 其余代码 // 路由仍传递currentMenu <Route path="/menus/:menuId" element={<MenusShow menu={currentMenu} />} /> }
验证要点
- 直接访问
/menus/:menuId时,控制台应打印匹配到的菜单数据,页面正常渲染内容。 - 从
MenusIndex点击进入详情页,数据正常显示。 - 页面刷新后,详情页仍能加载对应数据。
内容的提问来源于stack exchange,提问作者Adina Reiter
相关产品推荐
相关产品推荐

