javascript - 映射 Menu 对象导致多个菜单因状态而打开
问题描述
我的 Material UI 有问题<Menu>
。基本上,我正在映射 a<Card>
以显示一些数据和界面功能。我正在尝试<IconButton>
在每张卡上添加一个。单击一次,该按钮将打开一个菜单。目前我面临的问题是,当我单击 IconButton 时,所有菜单都在彼此之上打开(由于映射具有相同 state 属性的菜单项)。
<CardHeader
action={
<>
<IconButton
onClick={handleClick}
aria-label="settings">
<MoreVertIcon />
</IconButton>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Edit </MenuItem>
<MenuItem onClick={handleClose}>Delete</MenuItem>
</Menu>
</>
}
/>
由于菜单后面的阴影很大,您可以看出,这不是 CSS 的选择……这就是我所有的菜单都从我的<Card>
组件中堆叠起来的。我知道罪魁祸首是拥有一个打开关闭状态的财产。这个解决方案有什么“快速修复”吗?我不能对状态本身进行硬编码。
这是我返回生成的 map 函数的其余代码<Card>
。请检查我的<CardHeader>
. 请注意,我有两个<CardHeaders>
,那是因为我有一个条件来指示卡片使用哪个 CardHeader 。
const UserBuckets = (props) => {
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
if (!buckets || buckets.length === 0) return <p>Can not find any buckets, make one below!</p>;
return (
<React.Fragment style={{width:"90%"}}>
<Container style={{width:"90%"}} maxWidth="md" component="main">
<Grid container spacing={5} alignItems="stretch">
{buckets.map((bucket) =>
{
return (
<Grid item key={bucket.id} xs={12} sm={6} md={4} lg={4}>
<Card
className={classes.root}
classes={{ root: state.raised ? classes.cardHovered : "" }}
onMouseOver={() => setState({ shadow: 3 })}
onMouseOut={() => setState({ shadow: 1 })}
zdepth={state.shadow}
style={{ height: "100%", borderRadius:"30px"}}
>
{(!bucket || bucket.stock_list === null) &&
<CardHeader className={classes.bucketTitle} classes={{ title: classes.bucketTitle }}
title={
<>
<Link
color="textPrimary"
href={'dash/' + bucket.slug}
className={classes.link}
style={{ textDecoration: 'none' }}
>
{bucket.name.substr(0, 50)}
</Link>
</>
}
subheader="Add Stocks to get started!"
action={
<>
<IconButton
onClick={handleClick}
aria-label="settings">
<MoreVertIcon />
</IconButton>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
style={{boxShadow: 'none'}}
elevation={0}
>
<MenuItem onClick={handleClose}>Edit </MenuItem>
<MenuItem onClick={handleClose}>Delete</MenuItem>
</Menu>
</>
}
/>}
{bucket && bucket.stock_list != null &&
<CardHeader className="cardHeaderBucket"
title={bucket.name.substr(0, 20)}
subheader={bucket.about}
action={
<>
<IconButton
onClick={handleClick}
aria-label="settings">
<MoreVertIcon />
</IconButton>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Edit </MenuItem>
<MenuItem onClick={handleClose}>Delete</MenuItem>
</Menu>
</>
}
style={{margin:0}}
/>}
<CardContent className={classes.cardContent}>
{(!bucket || bucket.bucket_pos_neg === null) &&
<p style={{ textAlign: "center" }} >
Your Bucket is empty...
</p>}
{bucket && bucket.bucket_pos_neg != null &&
<div className={classes.bucketText}>
<Grid>
<Typography variant="subtitle1" color="textSecondary">
{/* {bucket.stock_list.join(",").substr(0, 15)}... */}
{"Total Stocks: " + bucket.stock_count}
</Typography>
<Typography variant="overline">
Return Donut
</Typography>
<BucketDoughnutDisplay data={bucket.bucket_pos_neg} />
</Grid>
</div>
}
</CardContent>
</Card>
</Grid>
);
})}
</Grid>
</Container>
</React.Fragment>
);
};
我怎样才能让我Menu
的每张卡都是独一无二的?我的方法的一个状态是引起重大问题。感谢您的帮助。
编辑:现在菜单没有弹出,也没有控制台错误。我已经进行了第二轮修改。请看这段代码
const UserBuckets = (props) => {
const [anchorEl, setAnchorEl] = React.useState(null);
const [currentIndex, setCurrentIndex] = useState(0);
const handleClick = (index) => (event) => {
setAnchorEl(event.currentTarget);
setCurrentIndex(index);
};
const handleClose = () => {
setAnchorEl(null);
};
const classes = useStyles();
if (!buckets || buckets.length === 0) return <p>Can not find any buckets, make one below!</p>;
return (
<React.Fragment>
<Container style={{width:"90%"}} maxWidth="md" component="main">
<Grid container spacing={5} alignItems="stretch">
{buckets.map((bucket, index) =>
{
return (
<Grid item key={bucket.id} xs={12} sm={6} md={4} lg={4}>
<Card
className={classes.root}
classes={{ root: state.raised ? classes.cardHovered : "" }}
onMouseOver={() => setState({ shadow: 3 })}
onMouseOut={() => setState({ shadow: 1 })}
zdepth={state.shadow}
style={{ height: "100%", borderRadius:"30px"}}
>
{(!bucket || bucket.stock_list === null) &&
<CardHeader className={classes.bucketTitle} classes={{ title: classes.bucketTitle }}
title={
<>
<Link
color="textPrimary"
href={'dash/' + bucket.slug}
className={classes.link}
style={{ textDecoration: 'none' }}
>
{bucket.name.substr(0, 50)}
</Link>
</>
}
subheader="Add Stocks to get started!"
action={
<>
<IconButton
onOpen={handleClick(index)}
aria-label="settings">
<MoreVertIcon />
</IconButton>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl) && currentIndex}
onClose={handleClose}
style={{boxShadow: 'none'}}
elevation={0}
>
<MenuItem onClick={handleClick(index)}>Edit </MenuItem>
<MenuItem onClick={handleClick(index)}>Delete</MenuItem>
</Menu>
</>
}
/>}
{bucket && bucket.stock_list != null &&
<CardHeader className="cardHeaderBucket"
title={bucket.name.substr(0, 20)}
subheader={bucket.about}
action={
<>
<IconButton
onOpen={handleClick(index)}
aria-label="settings">
<MoreVertIcon />
</IconButton>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl) && currentIndex}
onClose={handleClose}
>
<MenuItem onClick={handleClick(index)}>Edit </MenuItem>
<MenuItem onClick={handleClick(index)}>Delete</MenuItem>
</Menu>
</>
}
style={{margin:0}}
/>}
<CardContent className={classes.cardContent}>
{(!bucket || bucket.bucket_pos_neg === null) &&
<p style={{ textAlign: "center" }} >
Your Bucket is empty...
</p>}
{bucket && bucket.bucket_pos_neg != null &&
<div className={classes.bucketText}>
<Grid>
<Typography variant="subtitle1" color="textSecondary">
{/* {bucket.stock_list.join(",").substr(0, 15)}... */}
{"Total Stocks: " + bucket.stock_count}
</Typography>
<Typography variant="overline">
Return Donut
</Typography>
<BucketDoughnutDisplay data={bucket.bucket_pos_neg} />
</Grid>
</div>
}
</CardContent>
</Card>
</Grid>
);
})}
</Grid>
</Container>
</React.Fragment>
);
};
解决方案
尝试将当前索引与您的打开状态一起存储,以识别当前Menu
要打开的状态:
const [currentIndex, setCurrentIndex] = useState(0);
const handleClick = (index) => (event) => {
setAnchorEl(event.currentTarget);
setCurrentIndex(index);
};
buckets.map((bucket, index) => (
<>
<Grid>
<Menu open={Boolean(anchorEl) && currentIndex} {...props} />
</Grid>
<IconButton onOpen={handleClick(index)}/>
</>
))
推荐阅读
- android - Kotlin Gson 解析问题
- javascript - 字典的 Javascript 字典到基于 2nd tier key 的字典
- c# - Xamarin Forms 平台特定的 SetBarSelectedItemColor 无效
- javascript - 当 selectionLimit: 1 in angularjs dropdown multiselct 时默认选择不起作用
- apache-spark - Pyspark 在客户端模式下使用 Yarn Cluster Manager 冻结
- asp.net - 在 Windows Server 2016 的 Docker 容器中的 IIS Express 中运行 .NET Framework Web 应用程序 - 没有对临时 ASP.NET 文件的写入权限
- python - Python 元素树:写回 XML 文件时,名称空间位置已更改
- firebase - Firestore.getInstance():如何使用?
- fortran - 3D复数数组如何在内存中布局
- c# - (UWP) 如何为弹出对象设置动画