如何实现Card图片全屏显示?点击后图片重复问题解决
问题:点击卡片图片打开模态框总是显示同一张图片
在homepage.js组件中,卡片数据加载正常,但点击任意卡片的图片打开全屏模态框时,始终显示同一张图片。noimg为图片数组为空时的占位图,相关代码如下:
const [showModal, setShowModal] = useState(false); const handleModalShow = () => setShowModal(true); const handleModalClose = () => setShowModal(false);
dataposts.map((d)=>{return <> <Card style={{ width: '18rem' }}> <Card.Img variant="top" src={d.images[0]==null ? noimg : d.images[0].image} style={{marginLeft:10,marginTop:20, width: '15rem',height: '15rem' }} onClick={handleModalShow}/> <Card.Body> <Card.Title>{"name: "+d.name}</Card.Title> </Card.Body> <ListGroup className="list-group-flush"> <ListGroup.Item >{"number :"+ number}</ListGroup.Item> <ListGroup.Item>{"type:"+ type}</ListGroup.Item> </ListGroup> <Card.Body> <Link to={'Carddetails'} state={d.id} > <Button variant="primary" >details</Button> </Link> </Card.Body> <Modal show={showModal} onHide={handleModalClose} size="lg"> <Modal.Header closeButton></Modal.Header> <Modal.Body> <img src={d.images[0]==null ? noimg : d.images[0].image} alt={lname} style={{ width: '100%', height: 'auto' }} /> </Modal.Body> </Modal> </Card> </> })
问题原因
所有卡片的模态框共用同一个showModal状态,且模态框的图片源直接绑定循环变量d。当循环执行完毕后,d会指向数组的最后一项,因此无论点击哪个卡片,打开的模态框都会显示最后一张图片。同时每个卡片都渲染了一个模态框,造成冗余DOM。
解决方案
新增状态存储当前选中的图片地址,点击时传递对应图片地址到状态,模态框统一使用该状态的图片地址,且只渲染一个模态框实例。
修改后的代码:
- 更新状态与事件处理函数:
const [showModal, setShowModal] = useState(false); const [currentImage, setCurrentImage] = useState(''); // 存储当前要展示的图片地址 // 点击时传递当前卡片的图片地址,同时打开模态框 const handleModalShow = (imageUrl) => { setCurrentImage(imageUrl); setShowModal(true); }; const handleModalClose = () => setShowModal(false);
- 优化卡片循环渲染(移出模态框,添加唯一key):
dataposts.map((d) => { // 提前计算当前卡片的图片地址 const imageUrl = d.images[0] == null ? noimg : d.images[0].image; return ( <Card key={d.id} style={{ width: '18rem' }}> {/* 添加唯一key,避免React警告 */} <Card.Img variant="top" src={imageUrl} style={{marginLeft:10, marginTop:20, width: '15rem', height: '15rem' }} onClick={() => handleModalShow(imageUrl)} // 点击时传入当前图片地址 /> <Card.Body> <Card.Title>{"name: " + d.name}</Card.Title> </Card.Body> <ListGroup className="list-group-flush"> <ListGroup.Item >{"number :" + number}</ListGroup.Item> <ListGroup.Item>{"type:" + type}</ListGroup.Item> </ListGroup> <Card.Body> <Link to={'Carddetails'} state={d.id} > <Button variant="primary" >details</Button> </Link> </Card.Body> </Card> ); })
- 将模态框放在循环外部(只渲染一次):
<Modal show={showModal} onHide={handleModalClose} size="lg"> <Modal.Header closeButton></Modal.Header> <Modal.Body> <img src={currentImage} alt="selected image" style={{ width: '100%', height: 'auto' }} /> </Modal.Body> </Modal>
内容的提问来源于stack exchange,提问作者husam
相关产品推荐
相关产品推荐

