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

React-Static集成CMS菜单JSON:map未定义错误及子项处理求助

Hey there! Let's tackle your two issues one by one—first that pesky Cannot read property 'map' of undefined error, then handling nested child menu items.


1. Fixing the "Cannot read property 'map' of undefined" Error

This error pops up because when your component tries to run menus.items.map(), either menus itself is undefined, or menus.items hasn't been loaded yet (super common when fetching CMS data asynchronously). Here's how to fix it:

Option 1: Add Guard Clauses

Check if menus and menus.items exist before trying to map over them. You can also return a loading placeholder while waiting for data:

renderMenu() {
  // If no menus data exists, return null or a loading message
  if (!menus || !menus.items) {
    return <span>Loading menu...</span>;
  }

  return menus.items.map((menu) => {
    // Always add a unique key for React list items!
    return (
      <NavItem key={menu.id}>
        <Link to={menu.object_slug} className="nav-link">{menu.title}</Link>
      </NavItem>
    )
  })
}

Option 2: Use Optional Chaining (ES2020+)

A more concise way to handle null/undefined values with the optional chain operator (?.):

renderMenu() {
  return menus?.items?.map((menu) => (
    <NavItem key={menu.id}>
      <Link to={menu.object_slug} className="nav-link">{menu.title}</Link>
    </NavItem>
  )) || null;
}

If menus or menus.items is undefined, this will return null instead of throwing an error.


2. Handling Nested Child Menu Items

Since your menu has a nested children array, you'll need a recursive component to render all levels of the menu. Here's how to implement it:

Step 1: Create a Reusable Menu Item Component

This component will handle both top-level items and their children recursively:

const MenuItem = ({ item }) => {
  const hasChildren = item.children && item.children.length > 0;

  return (
    <NavItem key={item.id}>
      {/* Render the main menu link */}
      <Link to={item.object_slug} className="nav-link">{item.title}</Link>
      
      {/* If there are children, render them as a submenu */}
      {hasChildren && (
        <div className="submenu"> {/* Replace with your actual submenu component (e.g., NavDropdown) */}
          {item.children.map(child => (
            <MenuItem key={child.id} item={child} />
          ))}
        </div>
      )}
    </NavItem>
  );
};

Step 2: Update Your Render Method

Now use this component in your original renderMenu function:

renderMenu() {
  if (!menus || !menus.items) return <span>Loading menu...</span>;

  return menus.items.map((menuItem) => (
    <MenuItem key={menuItem.id} item={menuItem} />
  ));
}

Notes on Submenu Styling

  • Replace the generic <div className="submenu"> with whatever component your UI library uses (e.g., Bootstrap's NavDropdown, or a custom styled dropdown).
  • For items like "Practice Areas" (with a # URL), you might want to modify the component to make it a dropdown trigger instead of a clickable link—just add a conditional check for item.url === '#' to adjust the behavior.

内容的提问来源于stack exchange,提问作者C Porter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:22:43