是否使用材质UI中的网格列表和图标按钮作为单独的按钮并执行onClick操作



我正在尝试使用Material UI框架中的此网格列表:https://material-ui.com/components/grid-list/#grid-带有标题栏的列表

我正在尝试将onClick操作添加到每个磁贴的GridListTile组件和IconButton组件中。我已经能够做到这一点,但当我单击IconButton时,这也会注册为单击GridListTile。以下是我当前代码的一个片段:

<GridList cellHeight={200} className={classes.gridList} cols={Math.round(width/300)} spacing={6}>
{tileData.map((tile) => (
<GridListTile key={tile.img} onClick={() => {console1(tile.author)}}>
<img src={tile.img} alt={tile.title}/>
<GridListTileBar
title={tile.title}
subtitle={<span>by: {tile.author}</span>}
actionIcon={
<IconButton aria-label={`info about ${tile.title}`} className={classes.icon} onClick={() => {console2()}}>
<InfoIcon />
</IconButton>
}
/>
</GridListTile>
))}
</GridList>

console1和console2是我当前的函数,它们分别在单击GridListTile和IconButton时激活。本质上,当我点击图标按钮时,console1和console2都会激活,而只有console2应该激活。如果有人能帮助我了解正在发生的事情,并调整我的代码来解决这个问题,我将不胜感激。谢谢。

您需要设置要单击的元素的索引。

更新的Codesandbox:https://codesandbox.io/s/material-ui-grid-stacking-forked-2b1r4

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import GridList from "@material-ui/core/GridList";
import GridListTile from "@material-ui/core/GridListTile";
import GridListTileBar from "@material-ui/core/GridListTileBar";
import ListSubheader from "@material-ui/core/ListSubheader";
import IconButton from "@material-ui/core/IconButton";
import InfoIcon from "@material-ui/icons/Info";
// import tileData from './tileData';
const tileData = [
{
image: "https://via.placeholder.com/150",
title: "Title 1",
icon: "Title Icon 1"
},
{
image: "https://via.placeholder.com/150",
title: "Title 2",
icon: "Title Icon 2"
},
{
image: "https://via.placeholder.com/150",
title: "Title 3",
icon: "Title Icon 3"
}
];
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
flexWrap: "wrap",
justifyContent: "space-around",
overflow: "hidden",
backgroundColor: theme.palette.background.paper
},
gridList: {
width: 500,
height: 450
},
icon: {
color: "rgba(255, 255, 255, 0.54)"
}
}));
export default function GridComponent() {
const classes = useStyles();
const [title, setTitle] = React.useState("");
const [selected, setSelected] = React.useState();
function handleClick(index, title) {
console.log("title", title);
setSelected(index);
setTitle(title);
}
function handleIconClick(index, icon) {
console.log("icon", icon);
setSelected(index);
setTitle(icon);
}
return (
<div className={classes.root}>
<GridList cellHeight={180} className={classes.gridList}>
<GridListTile key="Subheader" cols={2} style={{ height: "auto" }}>
<ListSubheader component="div">{title}</ListSubheader>
</GridListTile>
{tileData.map((tile, index) => (
<GridListTile
className={index === selected ? "selected" : ""}
key={`${index}${title.title}`}
>
<img
src={tile.image}
alt={tile.title}
onClick={() => handleClick(index, tile.title)}
/>
<GridListTileBar
title={tile.title}
subtitle={<span>by: {tile.author}</span>}
actionIcon={
<IconButton
aria-label={`info about ${tile.title}`}
className={classes.icon}
onClick={() => handleIconClick(index, tile.icon)}
>
<InfoIcon />
</IconButton>
}
/>
</GridListTile>
))}
</GridList>
</div>
);
}

原因是事件冒泡。您可以了解有关事件冒泡的更多信息:https://www.tutorialspoint.com/what-is-event-bubbling-in-javascript

当您单击图标按钮时,单击事件会弹出到GridListTile。

因此,它们console2和console1都被触发了。

您需要使用stopPropagation将事件限制为冒泡。

这是

console1(e, author) {
console.log(author);
}
console2(e) {
e.stopPropagation();
console.log('console2');
}
<GridList cellHeight={200} className={classes.gridList} cols={Math.round(width/300)} spacing={6}>
{tileData.map((tile) => (
<GridListTile key={tile.img} onClick={(e) => {console1(e, tile.author)}}>
<img src={tile.img} alt={tile.title}/>
<GridListTileBar
title={tile.title}
subtitle={<span>by: {tile.author}</span>}
actionIcon={
<IconButton aria-label={`info about ${tile.title}`} className={classes.icon} onClick={(e) => {console2(e)}}>
<InfoIcon />
</IconButton>
}
/>
</GridListTile>
))}
</GridList>

现在

如果你点击图标按钮外的GridListTile,它将调用console1

如果你点击图标按钮,它将只调用console2。

相关内容