Aimless Blog

Reactのlightbox-reactを使ってみる

Tag:
reactnextjslightbox

lightbox系のライブラリではreact-medium-image-zoomが一押しですが、modalを開いてから次の画像にスライドできないので、 Reactのlightboxライブラリ「lightbox-react」を試してみました。
オリジナルのreact-image-lightboxはxボタン以外をクリックしても閉じることができなかったり、zoomした後の画像が動かせなかったりしたのでこちらを使用します。

インストール

npm install lightbox-react

example

公式のexampleはクラスコンポーネントで書かれてますが、hooksとnext.jsを使用します。
まずはindex.jsにimport

import React, { useState } from "react";
import Lightbox from "lightbox-react";
import "lightbox-react/style.css";

next.jsを使ってるならimport lightbox-react/style.cssを_app.jsに記述します。

(追記)next.js10以降はサードパーティ製のCSSをReactコンポーネントの中にインポートできるようになった。

import React, { useState } from "react";
import Lightbox from "lightbox-react";
import "lightbox-react/style.css";
import Homecss from "../styles/Home.module.css"

const images = [
  "001.jpg","002.jpg","003.jpg","004.jpg"
]

const title = ["Azura", "Ingun Black-Briar", "The Blue Palace", "Cicero"];

export default function Home() {
  const [photoIndex, setIndex] = useState(0);
  const [isOpen, setisOpen] = useState(false);

  return (
    <div>
      <main className={Homecss.main}>
        <h3>lightbox-reactのDEMO</h3>
        <div>
          {images.map((image, index) => (
            <img
              src={`/img/${image}`}
              alt={image}
              width="200px"
              onClick={() => {
                setisOpen(true), setIndex(index);
              }}
              key={index}
              className={Homecss.img}
            />
          ))}
        </div>

        {isOpen && (
          <Lightbox
            mainSrc={`/img/${images[photoIndex]}`}
            nextSrc={images[(photoIndex + 1) % images.length]}
            prevSrc={images[(photoIndex + images.length - 1) % images.length]}
            onCloseRequest={() => setisOpen(false)}
            onMovePrevRequest={() =>
              setIndex((photoIndex + images.length - 1) % images.length)
            }
            onMoveNextRequest={() => setIndex((photoIndex + 1) % images.length)}
            imageTitle={title[photoIndex]}
            imageCaption={title[photoIndex]}
           />
        )}
      </main>
    </div>
  );
}

公式のサンプルはボタンを押してモーダルを開くようになっていますが、画像をクリックして表示させたいので
photoIndexにセットする値は項目のインデックスを使用。

<Lightbox>以下でlightboxの色々なオプションを設定。
mainSrcCloseRequestが必須項目。
キャプションとタイトルはデフォルトでは何も表示されないので追加したり、デフォルトでズーム可なのをenableZoom={false}で不可にしたりできます。画像のダウンロードをできなくするdiscourageDownloadsをtrueにすると不具合があるので設定するのは止めましょう。

上のコードを実際に表示させたのがこれ→DEMO