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

React中MenusShow.jsx组件Props数据不显示问题求助

问题分析与解决方案

核心问题

  1. 状态声明顺序违规:useEffect 钩子在 menus 状态声明前调用,违反React Hooks使用规则,可能引发状态更新异常。
  2. 直接访问详情页数据丢失:currentMenu 仅在从 MenusIndex 点击时赋值,若直接通过URL访问 /menus/:menuId,currentMenu 为空对象,导致 MenusShow 无数据可渲染。
  3. 页面刷新后数据重置: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 15:35:13