You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

代码说明

  1. 仅展示主图:只保留第一个Item对应的图片作为页面可见元素,其余图片的Item通过display: none隐藏,不占用页面布局空间
  2. 触发画廊逻辑:通过主图的点击事件调用open(0),直接唤起画廊并默认展示第一张图片
  3. 适配API数据:自动遍历产品的photos数组生成所有Item,无需手动逐个添加,适配多图场景
  4. 清理冗余代码:移除原代码中useEffect自动打开弹窗的逻辑,改为用户主动点击触发

内容的提问来源于stack exchange,提问作者Jayesh Cholkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 10:07:51