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

React中使用Rsuite实现4级导航菜单报错求助

问题:Rsuite导航菜单无法实现4级子菜单

问题描述

  • 使用Rsuite构建导航菜单,需求是支持4级子菜单,但目前仅能实现「主菜单+1级子菜单」的结构
  • 注释的代码尝试实现多级菜单,但运行时报错:第31行无法对unknown执行map操作
  • 未注释的代码仅支持1级子菜单,可正常运行

报错信息

第31行无法对unknown执行map操作

原代码

import {NavLink} from 'react-router-dom';
import {Navbar, Nav} from 'rsuite';

export default function Header(){
  let menu = [
    {name: 'Varejos de Cão', key: 13, subitems: [ // e
      {name: 'Golden',        key: 1, subitems: [ // sub
        {name: 'Raças Pequenas', key: 2, subitems: [ // nvl2
          // {name: 'Adulto Carne', key: 3, link: '/golden_cao_ad_rpq_carne'}, // nvl3
          // {name: 'Adulto Frango', key: 4, link: '/golden_cao_ad_rpq_frango'},
          // {name: 'Filhote Carne', key: 5, link: '/golden_cao_fil_rpq_carne'},
        ]}
      ]}
    ]},
    {name: 'Varejos de Gato', key: 14, subitems: [
      {name: 'Golden',         key: 3, link: '#'}
    ]},
    {name: 'Nossas Lojas', key: 15, subitems: [
      {name: 'Tanque',         key: 6, link: '/tanque'},
      {name: 'Vila Isabel',           key: 7, link: '/vila'},
      {name: 'Grajau',          key: 8, link: '/grajau'},
      {name: 'Pechincha',          key: 9, link: '/pechincha'},
      {name: 'Catete',          key: 10, link: '/catete'},
      {name: 'Jacarepagua',          key: 12, link: '/jacarepagua'},
      {name: 'Tijuca',          key: 11, link: '/tijuca'}
    ]}
  ];

  // let menu_options = menu.map((e, k) => {
  //   let subs = e.subitems.map((nvl1, sub_k) => {
  //     let nvs2 = nvl1.subitems.map((nvl2, sub_k) => {
  //       return(
  //         <Nav.Item className="navigation-item" key={nvl2.key} eventKey={nvl2.key}><NavLink className="header-link" to={nvl2.link}>{nvl2.name}</NavLink></Nav.Item>
  //       );
  //     });

  //     return(
  //       <Nav.Menu title={nvl1.name} key={nvl1.key}>
  //         {nvs2}
  //       </Nav.Menu>
  //     );
  //   });

  //   return(
  //     <Nav.Menu title={e.name} key={k}>
  //       {subs}
  //     </Nav.Menu>
  //   );
  // });

  let menu_options = menu.map((e, k) => {
    let subs = e.subitems.map((sub, sub_k) => {
      return(
        <Nav.Item className="navigation-item" key={sub.key} eventKey={sub.key}><NavLink className="header-link" to={sub.link}>{sub.name}</NavLink></Nav.Item>
      );
    });

    return(
      <Nav.Menu title={e.name} key={e.key}>
        {subs}    
      </Nav.Menu>
    );
  });

  return(
    <div id="page-header">
      <nav id="menu-desktop">
        <div id="header-menu">
          <Navbar>
            <Navbar.Brand href="#">Dogão Pet Shop Varejos</Navbar.Brand>
            <Nav className="header-navigation">
              {/* <Nav.Item eventKey="1" href="/home">Home</Nav.Item> */}
              {menu_options}
            </Nav>
          </Navbar>
        </div>
      </nav>
      {/* <nav id="menu-mobile">
        <div id="header-menu">
          <Navbar>
            <Nav className="header-navigation">
              <Nav.Menu title="Menu">
                <Nav.Item className="navigation-item" eventKey="1"><NavLink className="header-link" to="/home">Home</NavLink></Nav.Item>
                {menu_options}
              </Nav.Menu>
            </Nav>
          </Navbar>
        </div>
      </nav> */}
    </div>
  )
}

问题原因

  1. 缺少空值判断:部分菜单项(比如Varejos de Gato下的Golden)没有subitems属性,代码直接调用nvl1.subitems.map时,nvl1.subitems为undefined,导致报错
  2. 硬编码层级限制:注释代码仅写了3层嵌套逻辑,无法支持4级子菜单,且没有区分「带链接的叶子节点」和「带子菜单的父节点」

修复方案:递归渲染多级菜单

通过递归函数自动处理任意层级的子菜单,同时增加空值判断避免报错:

import { NavLink } from 'react-router-dom';
import { Navbar, Nav } from 'rsuite';

export default function Header() {
  let menu = [
    {name: 'Varejos de Cão', key: 13, subitems: [
      {name: 'Golden', key: 1, subitems: [
        {name: 'Raças Pequenas', key: 2, subitems: [
          {name: 'Adulto Carne', key: 3, link: '/golden_cao_ad_rpq_carne'},
          {name: 'Adulto Frango', key: 4, link: '/golden_cao_ad_rpq_frango'},
          {name: 'Filhote Carne', key: 5, link: '/golden_cao_fil_rpq_carne'},
        ]}
      ]}
    ]},
    {name: 'Varejos de Gato', key: 14, subitems: [
      {name: 'Golden', key: 3, link: '#'}
    ]},
    {name: 'Nossas Lojas', key: 15, subitems: [
      {name: 'Tanque', key: 6, link: '/tanque'},
      {name: 'Vila Isabel', key: 7, link: '/vila'},
      {name: 'Grajau', key: 8, link: '/grajau'},
      {name: 'Pechincha', key: 9, link: '/pechincha'},
      {name: 'Catete', key: 10, link: '/catete'},
      {name: 'Jacarepagua', key: 12, link: '/jacarepagua'},
      {name: 'Tijuca', key: 11, link: '/tijuca'}
    ]}
  ];

  // 递归渲染菜单项,自动识别层级
  const renderMenuItem = (item) => {
    // 有子菜单时渲染为Nav.Menu
    if (item.subitems && item.subitems.length > 0) {
      return (
        <Nav.Menu title={item.name} key={item.key}>
          {item.subitems.map(subItem => renderMenuItem(subItem))}
        </Nav.Menu>
      );
    }
    // 没有子菜单时渲染为Nav.Item(叶子节点)
    return (
      <Nav.Item className="navigation-item" key={item.key} eventKey={item.key}>
        <NavLink className="header-link" to={item.link || '#'}>{item.name}</NavLink>
      </Nav.Item>
    );
  };

  const menu_options = menu.map(item => renderMenuItem(item));

  return (
    <div id="page-header">
      <nav id="menu-desktop">
        <div id="header-menu">
          <Navbar>
            <Navbar.Brand href="#">Dogão Pet Shop Varejos</Navbar.Brand>
            <Nav className="header-navigation">
              {menu_options}
            </Nav>
          </Navbar>
        </div>
      </nav>
      {/* <nav id="menu-mobile">
        <div id="header-menu">
          <Navbar>
            <Nav className="header-navigation">
              <Nav.Menu title="Menu">
                <Nav.Item className="navigation-item" eventKey="1"><NavLink className="header-link" to="/home">Home</NavLink></Nav.Item>
                {menu_options}
              </Nav.Menu>
            </Nav>
          </Navbar>
        </div>
      </nav> */}
    </div>
  )
}

关键改进点

  • 递归逻辑:自动适配任意层级的子菜单,无需修改代码即可支持4级甚至更多级
  • 安全判断:每次调用map前检查subitems是否存在且不为空,避免undefined报错
  • 节点区分:自动识别叶子节点(带链接)和父节点(带子菜单),渲染对应组件

内容的提问来源于stack exchange,提问作者Diogo Amaral

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 09:43:16