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

为什么自定义函数在componentDidMount前执行?@szhsin/react-menu使用报错

问题原因梳理

    1. JSX语法使用错误:你尝试把<SubMenu>开标签和</SubMenu>闭标签分开push到数组里,JSX不是字符串拼接,每一段JSX都会被编译为独立的React.createElement调用,拆分写标签属于语法错误,直接导致解析失败,这就是你还没到componentDidMount就报错的核心原因。
    1. 初始state未声明Categories字段:构造函数的初始state里只有name/apiData/isOpen三个属性,未定义Categories,首次渲染时该字段为undefined,虽然你写了== null的判断能命中,但前面的语法错误已经先触发了报错,导致判断逻辑没机会执行。
    1. 冗余代码问题:类组件中导入了仅函数组件使用的useState,还绑定了不存在的toggle方法,也会引发不必要的报错。

修复后的代码

直接重写递归生成菜单的逻辑,不要拆分JSX标签,递归返回完整的React元素即可:

import Config from 'config';
import { Menu, MenuItem, MenuButton, SubMenu } from '@szhsin/react-menu';
import '@szhsin/react-menu/dist/index.css';
import '@szhsin/react-menu/dist/transitions/slide.css';
import React from 'react';

class GetCategories extends React.Component {
    constructor() {
        super();
        this.state = {
            name: 'React',
            apiData: [],
            isOpen: false,
            // 初始化Categories字段
            Categories: null
        };
    }    

    componentDidMount() {
        console.log('app mounted');
        fetch(Config.apiUrl + "/api/Items/GetCategories")
            .then(data => data.json())
            .then(data => this.setState({ Categories: data }, () => console.log(data)));
    }    

    // 把递归函数提到render外面,避免每次渲染重复定义
    renderMenu = (category) => {
        if (category.children?.length > 0) {
            // 直接嵌套返回完整的SubMenu,不要拆分标签
            return (
                <SubMenu label={category.name} key={category.categoryId}>
                    {category.children.map(child => this.renderMenu(child))}
                </SubMenu>
            )
        } else {
            return <MenuItem key={category.categoryId}>{category.name}</MenuItem>
        }
    }

    render() {
        if (this.state.Categories == null) {
            console.log("NULL");
            return (
                <div>
                    <h1>加载中...</h1>
                </div>
            );
        }

        const categoriesStyled = this.state.Categories.map(cat => this.renderMenu(cat));

        return (
            <div>                    
                <Menu direction={'bottom'} menuButton={<MenuButton>Shop</MenuButton>} transition>
                    {categoriesStyled}
                </Menu>                        
            </div>
        );
    }
}
export default GetCategories;

核心修改点说明

  • 递归函数直接返回完整的JSX元素,不再拆分标签push到数组,符合React JSX的语法规则
  • 构造函数初始化了Categories字段,避免隐式undefined问题
  • 给每个菜单元素加了唯一key属性,避免React列表渲染警告
  • 移除了未使用的useState导入和不存在的toggle方法绑定
  • 用可选链?.判断children长度,避免不存在children字段时报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:45:06