嵌套菜单(子菜单) [英] Nested menu (sub-menu)
问题描述
我正在尝试实现子菜单(嵌套菜单).
值得一提的是,我正在使用 hydra 组件,并且之前没有使用 redux 的经验(因为这个特定问题,几天前开始学习它).
我已经按照 material-ui 提供的示例进行嵌套列表
import React, { Component } from 'react';从 'prop-types' 导入 PropTypes;从'react-redux'导入{连接};从 'recompose/compose' 导入 compose;从 '@material-ui/icons/Settings' 导入 SettingsIcon;从'@material-ui/icons/Label'导入LabelIcon;从'react-router-dom'导入{ withRouter };进口 {翻译,仪表板菜单项,菜单项链接,反应灵敏,来自反应管理员";从../visitors"导入访客;从'../orders'导入订单;从'../invoices'导入发票;从'../products'导入产品;从'../categories'导入类别;从../reviews"导入评论;从'./SubMenu'导入子菜单;类菜单扩展组件{状态 = {菜单目录:假,菜单销售:假,菜单客户:假,};静态 propTypes = {onMenuClick: PropTypes.func,注销:PropTypes.object,};handleToggle = 菜单 =>{this.setState(state => ({ [menu]: !state[menu] }));};使成为() {const { onMenuClick, open, logout, translate } = this.props;返回 (<div>{' '}<DashboardMenuItem onClick={onMenuClick}/><子菜单handleToggle={() =>this.handleToggle('menuSales')}isOpen={this.state.menuSales}sidebarIsOpen={打开}名称=pos.menu.sales"icon={ }><菜单项链接to={`/命令`}primaryText={translate(`resources.commands.name`, {smart_count: 2,})}leftIcon={ }onClick={onMenuClick}/><菜单项链接to={`/发票`}primaryText={translate(`resources.invoices.name`, {smart_count: 2,})}leftIcon={ }onClick={onMenuClick}/></子菜单><子菜单handleToggle={() =>this.handleToggle('menuCatalog')}isOpen={this.state.menuCatalog}sidebarIsOpen={打开}名称=pos.menu.catalog"icon={ }><菜单项链接to={`/products`}primaryText={translate(`resources.products.name`, {smart_count: 2,})}leftIcon={ }onClick={onMenuClick}/><菜单项链接to={`/categories`}primaryText={translate(`resources.categories.name`, {smart_count: 2,})}leftIcon={ }onClick={onMenuClick}/></子菜单><子菜单handleToggle={() =>this.handleToggle('menuCustomer')}isOpen={this.state.menuCustomer}sidebarIsOpen={打开}名称=pos.menu.customers"icon={ }><菜单项链接to={`/customers`}primaryText={translate(`resources.customers.name`, {smart_count: 2,})}leftIcon={ }onClick={onMenuClick}/><菜单项链接to={`/segments`}primaryText={translate(`resources.segments.name`, {smart_count: 2,})}leftIcon={ }onClick={onMenuClick}/></子菜单><菜单项链接to={`/评论`}primaryText={translate(`resources.reviews.name`, {smart_count: 2,})}leftIcon={ }onClick={onMenuClick}/><响应式xsmall={<菜单项链接到=/配置"primaryText={translate('pos.configuration')}leftIcon={ }onClick={onMenuClick}/>}中={空}/><响应式小={注销}medium={null}//传递 null 以在较大的设备上不渲染任何内容/>
);}}const mapStateToProps = state =>({打开:state.admin.ui.sidebarOpen,主题:state.theme,语言环境:state.i18n.locale,});const 增强 = compose(带路由器,连接(mapStateToProps,{}),翻译);导出默认增强(菜单);
I'm trying to implement Sub-menu (nested menu).
It's worth to mention that I'm using hydra component and don't have previous experience with redux (started learning it a few days ago because of this specific problem).
I've followed the example provided on material-ui for nested list https://material-ui.com/demos/lists/#nested-list. And tutorial from https://marmelab.com/react-admin/Theming.html#using-a-custom-menu for custom menu implementation.
So I have a few questions.
1) Can I have stateful component (MyMenu) just for handling toggling of menu items?
An example is not related to react-admin but its just example what I mean.
import React, { Component } from "react";
import { connect } from "react-redux";
import { addArticle } from "../actions/index";
const mapDispatchToProps = dispatch => {
return {
addArticle: article => dispatch(addArticle(article))
};
};
class ConnectedForm extends Component {
constructor() {
super();
this.state = {
title: ""
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ [event.target.id]: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
const { title } = this.state;
const id = uuidv1();
this.props.addArticle({ title, id });
this.setState({ title: "" });
}
render() {
const { title } = this.state;
return (
<form onSubmit={this.handleSubmit}>
<div className="form-group">
<label htmlFor="title">Title</label>
<input
type="text"
className="form-control"
id="title"
value={title}
onChange={this.handleChange}
/>
</div>
<button type="submit" className="btn btn-success btn-lg">
SAVE
</button>
</form>
);
}
}
const Form = connect(null, mapDispatchToProps)(ConnectedForm);
export default Form;
2) If not, can I achieve that by declaring a new state in store, for example, open: false, and then using the custom reducer to handle that.
3(bonus). If it's not a problem I would appreciate if someone can put me in the right direction which things to start learning first so I can less painfully manage to solve issues related to this amazing framework :)
The react-admin demo now shows a way to do so in examples/demo/src/layout/Menu.js:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import compose from 'recompose/compose';
import SettingsIcon from '@material-ui/icons/Settings';
import LabelIcon from '@material-ui/icons/Label';
import { withRouter } from 'react-router-dom';
import {
translate,
DashboardMenuItem,
MenuItemLink,
Responsive,
} from 'react-admin';
import visitors from '../visitors';
import orders from '../orders';
import invoices from '../invoices';
import products from '../products';
import categories from '../categories';
import reviews from '../reviews';
import SubMenu from './SubMenu';
class Menu extends Component {
state = {
menuCatalog: false,
menuSales: false,
menuCustomers: false,
};
static propTypes = {
onMenuClick: PropTypes.func,
logout: PropTypes.object,
};
handleToggle = menu => {
this.setState(state => ({ [menu]: !state[menu] }));
};
render() {
const { onMenuClick, open, logout, translate } = this.props;
return (
<div>
{' '}
<DashboardMenuItem onClick={onMenuClick} />
<SubMenu
handleToggle={() => this.handleToggle('menuSales')}
isOpen={this.state.menuSales}
sidebarIsOpen={open}
name="pos.menu.sales"
icon={<orders.icon />}
>
<MenuItemLink
to={`/commands`}
primaryText={translate(`resources.commands.name`, {
smart_count: 2,
})}
leftIcon={<orders.icon />}
onClick={onMenuClick}
/>
<MenuItemLink
to={`/invoices`}
primaryText={translate(`resources.invoices.name`, {
smart_count: 2,
})}
leftIcon={<invoices.icon />}
onClick={onMenuClick}
/>
</SubMenu>
<SubMenu
handleToggle={() => this.handleToggle('menuCatalog')}
isOpen={this.state.menuCatalog}
sidebarIsOpen={open}
name="pos.menu.catalog"
icon={<products.icon />}
>
<MenuItemLink
to={`/products`}
primaryText={translate(`resources.products.name`, {
smart_count: 2,
})}
leftIcon={<products.icon />}
onClick={onMenuClick}
/>
<MenuItemLink
to={`/categories`}
primaryText={translate(`resources.categories.name`, {
smart_count: 2,
})}
leftIcon={<categories.icon />}
onClick={onMenuClick}
/>
</SubMenu>
<SubMenu
handleToggle={() => this.handleToggle('menuCustomer')}
isOpen={this.state.menuCustomer}
sidebarIsOpen={open}
name="pos.menu.customers"
icon={<visitors.icon />}
>
<MenuItemLink
to={`/customers`}
primaryText={translate(`resources.customers.name`, {
smart_count: 2,
})}
leftIcon={<visitors.icon />}
onClick={onMenuClick}
/>
<MenuItemLink
to={`/segments`}
primaryText={translate(`resources.segments.name`, {
smart_count: 2,
})}
leftIcon={<LabelIcon />}
onClick={onMenuClick}
/>
</SubMenu>
<MenuItemLink
to={`/reviews`}
primaryText={translate(`resources.reviews.name`, {
smart_count: 2,
})}
leftIcon={<reviews.icon />}
onClick={onMenuClick}
/>
<Responsive
xsmall={
<MenuItemLink
to="/configuration"
primaryText={translate('pos.configuration')}
leftIcon={<SettingsIcon />}
onClick={onMenuClick}
/>
}
medium={null}
/>
<Responsive
small={logout}
medium={null} // Pass null to render nothing on larger devices
/>
</div>
);
}
}
const mapStateToProps = state => ({
open: state.admin.ui.sidebarOpen,
theme: state.theme,
locale: state.i18n.locale,
});
const enhance = compose(
withRouter,
connect(
mapStateToProps,
{}
),
translate
);
export default enhance(Menu);
这篇关于嵌套菜单(子菜单)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!