我正在运行MaterialUI-下一步,我尝试了抽屉的所有变体,但当抽屉中的项目被单击时,我无法关闭它。我知道临时变体允许我这样做,但当点击任何东西时,它就会关闭。我需要它关闭只有当一个ListItem被点击。
在我的例子中,我的抽屉里有一个ExpansionPanel,里面有列表和ListItems。点击ExpansionPanel不应该关闭抽屉,抽屉应该保持打开,因为我还没有准备好导航。但是,当我单击抽屉中的ListItem (它们包含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>我的内容存储在SystemMenu:中
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);我在其他帖子中看到,你可以用道具把onKeyDown={(open) => this.setState({ open: false })}传递给它的孩子。但我是新的反应,并有一些问题的概念。
基本上,我需要让onKeyDown为ListItems工作,而不是实际的抽屉。我可能需要也可能不需要将我的抽屉变量更改为onKeyDown属性的临时变量。不太确定。
(请记住,上面的链接提供了一个测试代码的操场。比我想要构建一个jFiddle来做出反应要好得多)
编辑
我想出了一种不同的方法,但不是我最喜欢的。
通过将SystemMenu中的内容移动到Menu.js文件(在这里,我的抽屉导入、函数和状态是动态的),我能够创建一个带有超时的handleClose函数,从而关闭它。这是一项功能:
handleClose = () => {
if (!this.state.open) {
return;
}
this.timeout = setTimeout(() => {
this.setState({ open: false });
this.setState({ expanded: null });
});
};这需要持久变体和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>接下来,在包含扩展面板和列表的系统菜单代码中,我将handleClose()函数添加到列表中,它导航并关闭抽屉和展开面板。如下所示:
<List
className="quickpanel-navigation"
onClick={() => { this.handleClose(); }}>
.... ListItems code here ....
</List>这是一个Ok方法,但我更希望在另一个文件中使用SystemMenu代码,并将其导入到这个文件中,并使用道具从SystemMenu.js文件中操作Menu.js文件中的关闭函数。如果还有人想继续帮我,我会很感激的。
发布于 2018-03-02 15:03:08
在演示中,它们将所有的ListItems包装在一个打开抽屉的div中:
<div
tabIndex={0}
role="button"
onClick={this.toggleDrawer('left', false)}
onKeyDown={this.toggleDrawer('left', false)}
>
{sideList}
</div>在这段代码中,toggleDrawer是一个函数,它设置抽屉的open支柱所使用的状态。因此,当一个键被按下或在列表的一个子列表中发生单击时,事件就会泡状到这些处理程序(只要不使用event.stopPropagation() )并改变状态。
在您的代码中,您不希望扩展程序的单击关闭抽屉,因此您必须以不同的方式处理这些事件。
可以将onClick处理程序添加到列表中:
<ExpansionPanelDetails>
<List onClick={ () => { /* close the drawer here */ } }>
<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>然后,当单击ListItems时,事件将冒泡到列表的处理程序,该处理程序设置状态,关闭抽屉。
根据代码的结构,您可能需要修改抽屉的实现,以便将函数传递给SystemMenu组件,以便列表上的单击处理程序可以设置其父组件的状态,因为this.setState会影响this的状态,而this是该组件的当前实例。它不会设置抽屉的状态。
更新:
根据你的评论,我加入了这一点。
在SystemMenu组件中:-接受一个名为closeDrawer的道具。-将此函数从道具中用作列表中的onClick处理程序
closeDrawer。this.closeDrawer传递为“`closeDrawer” <SystemMenu closeDrawer={this.closeDrawer} ...>这是从SystemMenu (子组件)中更改菜单(父组件)的本地状态的一种方法。
发布于 2019-11-01 13:34:50
通过MuiPaper将关闭处理程序通过PaperProps放在PaperProps上。
const handleClose = () => console.log('closing drawer');
const MyDrawer = () => <Drawer PaperProps={{onClick: handleClose}} />这将关闭当点击抽屉内任何地方的抽屉。
发布于 2018-03-02 15:02:09
假设您的抽屉位于类组件中,您可以这样做,以便从子组件中关闭它。
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>
)
}
}然后您可以从this.props.closeDrawer内部访问SystemMenu。听起来像是要为列表项添加到onClick处理程序中:
<ListItem
button
component="a"
href="/app/page1"
onClick={this.props.closeDrawer}
>
<ListItemText primary="Page 1" />
</ListItem>https://stackoverflow.com/questions/49071231
复制相似问题