我正在尝试使用json表示嵌套的侧边栏菜单,以表示导航的结构。不幸的是,我似乎无法克服
的烦人错误TypeError:无法读取null的属性“ Item3”。 (“ Item3”来自下面的json)。
我觉得为具有孩子的菜单项动态设置状态时做错了事,但是,我所做的正是在我阅读的其他示例中所做的事情。具体来说,我认为this.state [menuItem.name]引起了问题,因为最初没有与之相关的值。当我注释掉有关state [menuItem.name]的任何行时,问题就消失了。当我调试它时,json也被很好地读取。
这是我遵循的示例:https://medium.com/@vayamjain/making-a-nested-sidebar-menu-in-react-f8595031995e
这是我的代码:
import React, { Component } from 'react'
import menuItems from './menuItems.json'
import Divider from '@material-ui/core/Divider';
import Drawer from '@material-ui/core/Drawer';
import IconButton from '@material-ui/core/IconButton';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import MailIcon from '@material-ui/icons/Mail';
import MenuIcon from '@material-ui/icons/Menu';
import InboxIcon from '@material-ui/icons/MoveToInbox';
import classNames from 'classnames';
import ExpandLess from '@material-ui/icons/ExpandLess'
import ExpandMore from '@material-ui/icons/ExpandMore'
import Collapse from '@material-ui/core/Collapse'
import { withStyles } from '@material-ui/core/styles'
const styles = theme => ({
drawerHeader: {
display: 'flex',
alignItems: 'center',
padding: '0 8px',
...theme.mixins.toolbar,
justifyContent: 'flex-end',
},
})
export class SideBarMenu extends Component {
handleClick = item => {
this.setState(prevState => ({[item]: !prevState[item]}))
}
handleMenuRender = items => {
items.map(menuItem => {
console.log(menuItem.name)
if (!menuItem.children) {
return (
<div key={menuItem.name}>
<ListItem button key={menuItem.name}>
<ListItemIcon>
{<menuItem.icon />}
</ListItemIcon>
<ListItemText inset primary={menuItem.name} />
</ListItem>
</div>
);
}
return (
<div key={menuItem.name}>
<ListItem button key={menuItem.name} >
<ListItemIcon>
{<menuItem.icon />}
</ListItemIcon>
<ListItemText inset primary={menuItem.name} />
{this.state[menuItem.name] ? <ExpandLess /> : <ExpandMore /> }
<Collapse in={menuItem.name} timeout="auto" unmountOnExit>
{this.handleMenuRender(menuItem.children)}
</Collapse>
</ListItem>
</div>
);
});
}
render() {
const { classes, theme } = this.props;
return (
<div>
<Drawer
className={classes.drawer}
variant="persistent"
anchor="left"
open={this.props.isDrawerOpen}
classes={{
paper: classes.drawerPaper,
}}
>
<div className={classes.drawerHeader}>
<IconButton onClick={this.props.handleDrawerClose}>
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
</IconButton>
</div>
<Divider />
<List>
{this.handleMenuRender(menuItems.data)}
</List>
</Drawer>
</div>
);
}
}
export default withStyles(styles, { withTheme: true })(SideBarMenu);
我正在读取的json:
{
"data" : [
{
"name": "Item1",
"url": "/item1",
"icon": "MailIcon"
},
{
"name": "Item2",
"url": "/item2"
},
{
"name": "Item3",
"children": [
{
"name": "Child31",
"url": "/child31"
},
{
"name": "Child32",
"url": "/child32"
},
{
"name": "Child32",
"url": "/child32"
}
]
},
{
"name": "Item4",
"children": [
{
"name": "Child41",
"url": "/child41"
},
{
"name": "Child42",
"url": "/child42"
},
{
"name": "Child43",
"children": [
{
"name": "Child431",
"url": "/child431"
},
{
"name": "Child432",
"url": "/child432,"
},
{
"name": "Child433",
"url": "/child433"
}
]
}
]
}
]
}
确实坚持使用此工具,感谢您的任何帮助!