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

