react-photoswipe-gallery使用问题:单图展示并点击唤起画廊
集成react-photoswipe-gallery的问题解决
需求与问题
UI仅展示单张图片,用户点击该图片时弹出包含对应产品所有图片的react-photoswipe-gallery画廊弹窗,尝试多种方法未实现预期效果。
参考代码
import React, { useEffect } from "react"; import "photoswipe/dist/photoswipe.css"; import { Gallery, Item, useGallery } from "react-photoswipe-gallery"; // import useGallery from "react-photoswipe-gallery"; const MyGallery = () => { const { open } = useGallery(); console.log(open); useEffect(() => { open(1); // you can open second slide by calling open(1) in useEffect }, [open]); return ( <Gallery> <Item original="https://placekitten.com/1024/768?image=1" thumbnail="https://placekitten.com/80/60?image=1" width="100" height="100" > {({ ref, open }) => ( <img ref={ref} onClick={open} width="100" height="100" src="https://placekitten.com/1024/768?image=1" alt="Kitten 1" /> )} </Item> <Item original="https://placekitten.com/1024/768?image=2" thumbnail="https://placekitten.com/80/60?image=2" width="100" height="100" // onClick={handleItemClick} > {({ ref }) => ( <div ref={ref}> {/* <img ref={ref} width="100" height="100" // src="https://placekitten.com/1024/768?image=2" alt="Kitten 2" /> */} </div> )} </Item> {/* Add more Item components for additional photos */} </Gallery> ); }; export default MyGallery;
示例API响应
const products = [ { productName: 'Product 1', photos: [ { src: 'https://example.com/photo1.jpg', w: 1024, h: 768 }, { src: 'https://example.com/photo2.jpg', w: 1024, h: 768 }, { src: 'https://example.com/photo3.png', w: 1024, h: 768 }, ], }, { productName: 'Product 2', photos: [ { src: 'https://example.com/photo4.jpg', w: 1024, h: 768 }, { src: 'https://example.com/photo5.jpg', w: 1024, h: 768 }, { src: 'https://example.com/photo6.png', w: 1024, h: 768 }, ], }, ];
期望效果
点击页面展示的单张图片,弹出包含对应产品所有图片的画廊弹窗,可在弹窗内切换查看全部图片。
解决方案
核心思路
- 仅渲染一个可见的
Item组件作为页面展示图,其余图片的Item组件隐藏渲染,确保画廊能识别所有图片资源 - 通过点击事件触发画廊弹窗,默认打开第一张图片
优化后的代码
import React from "react"; import "photoswipe/dist/photoswipe.css"; import { Gallery, Item, useGallery } from "react-photoswipe-gallery"; const ProductGallery = ({ product }) => { const { open } = useGallery(); const mainPhoto = product.photos[0]; // 点击主图打开画廊,默认显示第一张 const handleOpenGallery = () => open(0); return ( <Gallery> {/* 页面可见的主图Item */} <Item original={mainPhoto.src} width={mainPhoto.w} height={mainPhoto.h} > {({ ref }) => ( <img ref={ref} onClick={handleOpenGallery} src={mainPhoto.src} alt={`${product.productName} 主图`} style={{ maxWidth: "300px", cursor: "pointer" }} /> )} </Item> {/* 隐藏的其他图片Item,用于画廊加载全部资源 */} {product.photos.slice(1).map((photo, index) => ( <Item key={index + 1} original={photo.src} width={photo.w} height={photo.h} > {({ ref }) => <div ref={ref} style={{ display: "none" }} />} </Item> ))} </Gallery> ); }; // 组件使用示例 const App = () => { const products = [ { productName: 'Product 1', photos: [ { src: 'https://example.com/photo1.jpg', w: 1024, h: 768 }, { src: 'https://example.com/photo2.jpg', w: 1024, h: 768 }, { src: 'https://example.com/photo3.png', w: 1024, h: 768 }, ], }, ]; return ( <div> {products.map((product) => ( <div key={product.productName}> <h3>{product.productName}</h3> <ProductGallery product={product} /> </div> ))} </div> ); }; export default App;
代码说明
- 仅展示主图:只保留第一个
Item对应的图片作为页面可见元素,其余图片的Item通过display: none隐藏,不占用页面布局空间 - 触发画廊逻辑:通过主图的点击事件调用
open(0),直接唤起画廊并默认展示第一张图片 - 适配API数据:自动遍历产品的
photos数组生成所有Item,无需手动逐个添加,适配多图场景 - 清理冗余代码:移除原代码中
useEffect自动打开弹窗的逻辑,改为用户主动点击触发
内容的提问来源于stack exchange,提问作者Jayesh Cholkar
相关产品推荐
相关产品推荐

