反应 Material UI 卡片 w/Modal
React Material UI Cards w/Modal
我正在尝试配置此 React JS / Material UI 模态对话框,以便当用户单击卡片时,它会打开相应的 full-sized 图片(带有标题和副标题)。每张卡的数据都映射自 JSON 文件(通过 AXIOS)。
我可以打开模态 window,但它显示了模态中的所有卡片图像,并且它们相互堆叠。 handleOpen()
函数中的 console.log("SELECTED CAMPAIGN: ", selectedCampaign)
代码落后于单击一次...它实际上记录了在当前单击事件之前选择的 object。
我对功能组件和挂钩比较陌生,所以我知道我犯了一些简单而根本的错误...请帮我找出正确的设置方法:
const CampaignItems = ({campaigns, loading}) => {
const classes = useStyles();
const [open, setOpen] = useState(false);
const [selectedCampaign, setSelectedCampaign] = useState();
const handleOpen = (campaign) => {
setSelectedCampaign(campaign);
console.log("SELECTED CAMPAIGN: ", selectedCampaign);
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
..................
<div>
<GridContainer>
{campaigns && search(campaigns).map((campaign) => (
<GridItem key={campaign.id} xs={12} sm={6} md={4}>
<Card className={classes.root}>
<CardActionArea>
<CardMedia
component="img"
alt={campaign.alt}
height="140"
image={campaign.image}
title={campaign.title}
onClick={() => handleOpen(campaign)}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{campaign.title}
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
{campaign.subtitle}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<IconButton
size="medium"
color="primary"
aria-label="More Information"
onClick={() => handleOpen(campaign)}
>
<InfoIcon />
</IconButton>
<Modal
className={classes.modal}
open={open}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500
}}
>
<Fade
in={open}
>
<div className={classes.paper}>
<h6>{campaign.title}</h6>
<p>{campaign.subtitle}</p>
<img src={campaign.image} />
</div>
</Fade>
</Modal>
</CardActions>
</Card>
</GridItem>
))}
</GridContainer>
</div>
..................
你的问题似乎是你只使用一个 open
状态来触发你的模式打开,所以它们都是同时触发打开的。
我建议改为使用您正在与之交互的卡片的 selectedCampaign
,并使用与要打开的模式相匹配的活动 ID。
const CampaignItems = ({campaigns, loading}) => {
...
const [selectedCampaign, setSelectedCampaign] = useState(null);
const handleOpen = (campaign) => () => {
setSelectedCampaign(selectedCampaign =>
selectedCampaign.id === campaign.id ? null : campaign
);
};
const handleClose = () => {
setSelectedCampaign(null);
};
...
<div>
<GridContainer>
{campaigns && search(campaigns).map((campaign) => (
<GridItem key={campaign.id} xs={12} sm={6} md={4}>
<Card className={classes.root}>
<CardActionArea>
<CardMedia
...
onClick={handleOpen(campaign)}
/>
...
</CardActionArea>
<CardActions>
<IconButton
...
onClick={handleOpen(campaign)}
>
...
</IconButton>
<Modal
...
open={selectedCampaign.id === campaign.id} // <-- check id match
onClose={handleClose}
...
>
...
</Modal>
</CardActions>
</Card>
</GridItem>
))}
</GridContainer>
</div>
...
我正在尝试配置此 React JS / Material UI 模态对话框,以便当用户单击卡片时,它会打开相应的 full-sized 图片(带有标题和副标题)。每张卡的数据都映射自 JSON 文件(通过 AXIOS)。
我可以打开模态 window,但它显示了模态中的所有卡片图像,并且它们相互堆叠。 handleOpen()
函数中的 console.log("SELECTED CAMPAIGN: ", selectedCampaign)
代码落后于单击一次...它实际上记录了在当前单击事件之前选择的 object。
我对功能组件和挂钩比较陌生,所以我知道我犯了一些简单而根本的错误...请帮我找出正确的设置方法:
const CampaignItems = ({campaigns, loading}) => {
const classes = useStyles();
const [open, setOpen] = useState(false);
const [selectedCampaign, setSelectedCampaign] = useState();
const handleOpen = (campaign) => {
setSelectedCampaign(campaign);
console.log("SELECTED CAMPAIGN: ", selectedCampaign);
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
..................
<div>
<GridContainer>
{campaigns && search(campaigns).map((campaign) => (
<GridItem key={campaign.id} xs={12} sm={6} md={4}>
<Card className={classes.root}>
<CardActionArea>
<CardMedia
component="img"
alt={campaign.alt}
height="140"
image={campaign.image}
title={campaign.title}
onClick={() => handleOpen(campaign)}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{campaign.title}
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
{campaign.subtitle}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<IconButton
size="medium"
color="primary"
aria-label="More Information"
onClick={() => handleOpen(campaign)}
>
<InfoIcon />
</IconButton>
<Modal
className={classes.modal}
open={open}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500
}}
>
<Fade
in={open}
>
<div className={classes.paper}>
<h6>{campaign.title}</h6>
<p>{campaign.subtitle}</p>
<img src={campaign.image} />
</div>
</Fade>
</Modal>
</CardActions>
</Card>
</GridItem>
))}
</GridContainer>
</div>
..................
你的问题似乎是你只使用一个 open
状态来触发你的模式打开,所以它们都是同时触发打开的。
我建议改为使用您正在与之交互的卡片的 selectedCampaign
,并使用与要打开的模式相匹配的活动 ID。
const CampaignItems = ({campaigns, loading}) => {
...
const [selectedCampaign, setSelectedCampaign] = useState(null);
const handleOpen = (campaign) => () => {
setSelectedCampaign(selectedCampaign =>
selectedCampaign.id === campaign.id ? null : campaign
);
};
const handleClose = () => {
setSelectedCampaign(null);
};
...
<div>
<GridContainer>
{campaigns && search(campaigns).map((campaign) => (
<GridItem key={campaign.id} xs={12} sm={6} md={4}>
<Card className={classes.root}>
<CardActionArea>
<CardMedia
...
onClick={handleOpen(campaign)}
/>
...
</CardActionArea>
<CardActions>
<IconButton
...
onClick={handleOpen(campaign)}
>
...
</IconButton>
<Modal
...
open={selectedCampaign.id === campaign.id} // <-- check id match
onClose={handleClose}
...
>
...
</Modal>
</CardActions>
</Card>
</GridItem>
))}
</GridContainer>
</div>
...