Reactjs MaterialUI下一个关闭抽屉上的子项单击
我正在运行MaterialUI Next,我已经尝试了抽屉的所有变体,但当单击抽屉中的项目时,我无法将其关闭。我知道临时变量允许我这样做,但它会在单击任何内容时关闭。我需要它仅在单击ListItem时关闭 在我的例子中,抽屉中有一个扩展面板,其中包含列表和列表项。单击ExpansionPanel不应该关闭抽屉,抽屉应该保持打开状态,因为我还没有准备好离开。但是,当我单击抽屉中的列表项(它们包含Reactjs MaterialUI下一个关闭抽屉上的子项单击,reactjs,material-ui,Reactjs,Material Ui,我正在运行MaterialUI Next,我已经尝试了抽屉的所有变体,但当单击抽屉中的项目时,我无法将其关闭。我知道临时变量允许我这样做,但它会在单击任何内容时关闭。我需要它仅在单击ListItem时关闭 在我的例子中,抽屉中有一个扩展面板,其中包含列表和列表项。单击ExpansionPanel不应该关闭抽屉,抽屉应该保持打开状态,因为我还没有准备好离开。但是,当我单击抽屉中的列表项(它们包含component=“a”项)时,抽屉应该关闭,并且component=“a”导航到其href 我的代码
component=“a”
项)时,抽屉应该关闭,并且component=“a”导航到其href
我的代码是非常基本和香草,几乎完全是从。他们也有一个操场来测试代码。但无论如何,这里是我的一些相关代码
我的抽屉:
<Drawer
variant="persistent" //I tried "temporary", and "permanent" as well
elevation={16}
anchor="right"
open={this.state.open}
// onClick={(open) => this.setState({ open: false })}
// onKeyDown={(open) => this.setState({ open: false })}>
<SystemMenu />
</Drawer>
import React from 'react';
import { withStyles } from 'material-ui-next/styles';
import List, { ListItem, ListItemText } from 'material-ui-next/List';
import ExpansionPanel, { ExpansionPanelDetails, ExpansionPanelSummary } from 'material-ui-next/ExpansionPanel';
import ListSubheader from 'material-ui-next/List/ListSubheader';
import {ChevronDown} from 'mdi-material-ui';
import Grid from 'material-ui-next/Grid';
const OTHERPAGES = require('data/pages.js');
const systemMenuData = OTHERPAGES['systemMenuPagesItems'];
class SystemMenu extends React.Component {
constructor(props) {
super(props);
this.state = {
expanded: null,
};
}
handleChange = panel => (event, expanded) => {
this.setState({
open: false,
expanded: expanded ? panel : false,
});
};
render() {
const { expanded, open } = this.state;
return (
<div>
<Grid
container>
<Grid item xs={12} style={{padding: 0}}>
<ListSubheader component="div">MENU ITEMS</ListSubheader>
</Grid>
</Grid>
<Grid
container>
<Grid item xs={12}>
<ExpansionPanel
expanded={expanded === 'panel1'}
onChange={this.handleChange('panel1')}>
<ExpansionPanelSummary
expandIcon={<ChevronDown />}>
Players
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<List>
<ListItem
button
component="a"
href="/app/page1">
<ListItemText primary="Page 1" />
</ListItem>
<ListItem
button
component="a"
href="/app/page2">
<ListItemText primary="Page 2" />
</ListItem>
<ListItem
button
component="a"
href="/app/page3">
<ListItemText primary="Page 3" />
</ListItem>
</List>
</ExpansionPanelDetails>
</ExpansionPanel>
</Grid>
</Grid>
</div>
);
}
}
export default withStyles(styles)(SystemMenu);
这需要持久变量和handleOpen()
函数来保持抽屉打开,直到我单击具有handleClose()函数的列表。我的抽屉现在看起来像这样
<Drawer
variant="persistent"
elevation={16}
anchor="right"
open={this.state.open}
onClick={() => { this.handleOpen(); }}>
...
My System Menu code in here, not too happy about this part. :(
...
</Drawer>
这是一个不错的方法,但我更希望将SystemMenu代码放在另一个文件中并导入到该文件中,然后使用道具从SystemMenu.js文件中操作Menu.js文件中的关闭函数。如果其他人想继续帮助我,我将不胜感激。假设您的抽屉位于类组件中,您将执行类似操作,从子组件关闭它
class MyComponent extends React.Component {
constructor(props){
super(props)
this.state = {
open: false,
}
}
closeDrawer = () => this.setState({ open: false })
render() {
return (
<Drawer
elevation={16}
anchor="right"
open={this.state.open}
onKeyDown={this.closeDrawer}
>
<SystemMenu
closeDrawer={this.closeDrawer}
/>
</Drawer>
)
}
}
在中,他们将所有列表项包装在一个div中,该div用于处理关闭抽屉的操作:
{侧列表}
在此代码中,toggleDrawer
是一个函数,用于设置抽屉的open
属性所使用的状态。因此,当按下一个键或在列表的一个子项中发生单击时,事件会出现在这些处理程序中(只要不使用event.stopPropagation()
),并且状态会更改
在代码中,您不希望扩展器单击关闭抽屉,因此必须以不同的方式处理这些事件
您可以将onClick
处理程序添加到列表中:
{/*在此关闭抽屉*/}>
然后,当单击ListItems时,事件将冒泡到列表的处理程序,该处理程序设置状态,关闭抽屉
根据代码的结构,您可能需要修改抽屉的实现,以便将函数传递给SystemMenu
组件,以便其列表上的单击处理程序可以设置其父级的状态,因为this.setState
会影响this
的状态,this
是该组件的当前实例。它不会设置抽屉的状态
更新:
<Drawer
variant="persistent" //I tried "temporary", and "permanent" as well
elevation={16}
anchor="right"
open={this.state.open}
// onClick={(open) => this.setState({ open: false })}
// onKeyDown={(open) => this.setState({ open: false })}>
<SystemMenu />
</Drawer>
import React from 'react';
import { withStyles } from 'material-ui-next/styles';
import List, { ListItem, ListItemText } from 'material-ui-next/List';
import ExpansionPanel, { ExpansionPanelDetails, ExpansionPanelSummary } from 'material-ui-next/ExpansionPanel';
import ListSubheader from 'material-ui-next/List/ListSubheader';
import {ChevronDown} from 'mdi-material-ui';
import Grid from 'material-ui-next/Grid';
const OTHERPAGES = require('data/pages.js');
const systemMenuData = OTHERPAGES['systemMenuPagesItems'];
class SystemMenu extends React.Component {
constructor(props) {
super(props);
this.state = {
expanded: null,
};
}
handleChange = panel => (event, expanded) => {
this.setState({
open: false,
expanded: expanded ? panel : false,
});
};
render() {
const { expanded, open } = this.state;
return (
<div>
<Grid
container>
<Grid item xs={12} style={{padding: 0}}>
<ListSubheader component="div">MENU ITEMS</ListSubheader>
</Grid>
</Grid>
<Grid
container>
<Grid item xs={12}>
<ExpansionPanel
expanded={expanded === 'panel1'}
onChange={this.handleChange('panel1')}>
<ExpansionPanelSummary
expandIcon={<ChevronDown />}>
Players
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<List>
<ListItem
button
component="a"
href="/app/page1">
<ListItemText primary="Page 1" />
</ListItem>
<ListItem
button
component="a"
href="/app/page2">
<ListItemText primary="Page 2" />
</ListItem>
<ListItem
button
component="a"
href="/app/page3">
<ListItemText primary="Page 3" />
</ListItem>
</List>
</ExpansionPanelDetails>
</ExpansionPanel>
</Grid>
</Grid>
</div>
);
}
}
export default withStyles(styles)(SystemMenu);
根据你的评论,我添加了这一点
在系统菜单组件中:
-接受名为closeDrawer
的道具。
-使用props中的此函数作为列表上的onClick
处理程序
- 在菜单组件中:
- 添加一个函数来关闭抽屉,现在我们称它为
closeDrawer
- 呈现系统菜单时,将此.closeDrawer传递为“closeDrawer”
这是从SystemMenu(子菜单)中更改父组件菜单的本地状态的一种方法。通过PaperProps将关闭处理程序放置在MuiPaper上:
const handleClose = () => console.log('closing drawer');
const MyDrawer = () => <Drawer PaperProps={{onClick: handleClose}} />
consthandleclose=()=>console.log('closing drawer');
常量MyDrawer=()=>
这将在单击抽屉内的任何位置时关闭抽屉。对不起,我忘了提到系统菜单在一个单独的文件中,我正在导入包含抽屉的文件中。它无法识别ToggleDrawer函数,因为它是在一个单独的文件中声明的。以及它在SystemMenu文件中也没有声明的Drawer组件,但它是包含该Drawer的Menu.js。这就是为什么我认为道具是正确的方法。这不是道具应该做的吗?操作文件外部存在的函数?在它的父级?我想出了一个方法让它工作,但我必须在菜单文件中有系统菜单代码,这样我才能访问导入和功能。请参阅我的编辑+谢谢你的工作,因为你让我的齿轮转动。然而,我的问题仍然存在。我更希望能够从另一个文件中的子代码操纵抽屉。我知道它们位于不同的文件中,这就是为什么我写道,您需要从定义抽屉的位置向SystemMenu传递一个函数。在呈现抽屉的类中创建一个
closeDrawer
函数,并在SystemMenu组件中显示一个可以接受它的道具。然后在SystemMenu组件中,将其用作列表的单击处理程序。@LOTUSMS在我拼出来的地方看到更新的答案。
const handleClose = () => console.log('closing drawer');
const MyDrawer = () => <Drawer PaperProps={{onClick: handleClose}} />