React でウィンドウサイズが小さいときだけスライドショー表示をする方法

JavaScriptReact

ピンポイントな小ネタですが、 React で「ウィンドウサイズが大きいときは画像をそのまま並べて、ウィンドウサイズが小さいときは画像をスライドショー表示する方法」についてです。

今回はスライドショーの例ですが、この方法は「画面幅によって出力コンポーネントを切り替える方法」として一般化することもできます。

今回は以下のパッケージを使用します。

  • react 17.x.x
  • react-slick 0.27.14
  • slick-carousel 1.8.1

実現するには大きく 2 つのことを行う必要があります。

  1. ウィンドウサイズによって出力コンポーネントを切り替える
  2. スライドショーを生成する

1 は、 useState()useEffect()window オブジェクトの resize イベントを使って、ウィンドウサイズのしきい値で処理を分岐すれば OK です。

2 は単純にスライドショーを作ります。 自作でもよいですが react-slick 等の定番ライブラリを使うと高品質なものがかんたん確実に作れます。

この 1 と 2 を実現する ImageGallery コンポーネントを作ってみると次のようになります:

/**
 * ImageGallery
 */

import React, { useState, useEffect } from "react"
import Slider from "react-slick"
import "slick-carousel/slick/slick.css"
import "slick-carousel/slick/slick-theme.css"

// 画面幅がこの値に満たないときはスライドショー表示する
WIDTH_THRESHOLD = 768

const ImageGallery = ({ images }) => {
  const [width, setWidth] = useState(null)
  const updateWidth = (event) => {
    setWidth(window.innerWidth)
  }

  useEffect(() => {
    window.addEventListener(`resize`, updateWidth, {
      capture: false,
      passive: true,
    })

    return () => window.removeEventListener(`resize`, updateWidth)
  })

  // 初期表示時に画面幅に合わないコンポーネントが一瞬表示されてしまうのを防ぐ
  if (width === null) {
    return ``
  }

  if (width < WIDTH_THRESHOLD) {
    // 画像をスライドショー表示する
    return (
      <Slider>
        {images.map((image) => (
          <div key={image.src}>
            <img src={image.src} alt={image.alt} />
          </div>
        ))}
      </Slider>
    )
  }

  // 画像をそのまま並べる
  return (
    ...
  )
}

width を定義している useState(null) のところは、もしここで window オブジェクトに確実にアクセスできるようであれば useState(window.innerWidth) と書いてしまってもよいと思います。 そうした場合 if (width === null) の部分は削除可能です。

以上です。

参考


アバター
後藤隼人 ( ごとうはやと )

Python や PHP を使ってソフトウェア開発やウェブ制作をしています。詳しくはこちら