※記事のURLの一部は広告を含みます。

【React】ページ上部では表示しないトップへ戻るボタンを作る【外部ライブラリなし】の絵文字

【React】ページ上部では表示しないトップへ戻るボタンを作る【外部ライブラリなし】

2022-04-22

2022-04-22

はじめに

こんにちは!ブックマークしたサイトをやっと整理したこふです。

この記事では、本ブログの右下にもある「ページの一番上へ戻るボタン」の作り方を解説します。

デモGif画像


注意 ❗

以下の実装がベストプラクティスとは限りませんので、あくまで参考になさってください。


環境

React 以外の外部ライブラリは当然用いません。当然、Next.jsGatsby.js に組み込めます。

1node -v 2v16.14.0

アイコンは各自で svg ファイルを読み込む・書き込むで対応 OK です

package.json
1{ 2 "dependencies": { 3 ... 4 "react": "^17.0.2", 5 "react-dom": "^17.0.2", 6 "react-icons": "^4.3.1", 7 ... 8 }, 9 "devDependencies": { 10 ... 11 "autoprefixer": "^10.4.0", 12 "postcss": "^8.4.5", 13 "tailwindcss": "^3.0.7", 14 "typescript": "4.5.4" 15 ... 16 } 17}

ソースコード

実際のソースコードです。動作確認済み。

ScrollToTop.tsx
1import { useEffect, useState } from 'react' 2import { HiChevronDoubleUp } from 'react-icons/hi' 3import IconButton from '../IconButton/IconButton' 4 5const PAGE_Y_OFFSET = 200 6 7const ScrollToTop = () => { 8 const [show, setShow] = useState<boolean>(false) 9 10 const changeShow = () => { 11 if (window.pageYOffset > PAGE_Y_OFFSET) { 12 setShow(true) 13 } else { 14 setShow(false) 15 } 16 } 17 18 const onScrollTop = () => { 19 window.scroll({ top: 0, behavior: 'smooth' }) 20 } 21 22 useEffect(() => { 23 window.addEventListener('scroll', changeShow) 24 return () => window.removeEventListener('scroll', changeShow) 25 }, []) 26 27 if (show) 28 return ( 29 <div className="fixed bottom-10 right-10 z-10"> 30 <IconButton Icon={HiChevronDoubleUp} onClick={onScrollTop} /> 31 </div> 32 ) 33 else return null 34} 35 36export default ScrollToTop

ソースコードの解説

本来は UI とロジックが混在すべきでないですが、簡単のためファイルは 1 つにします。

ライブラリ群

1import { useEffect, useState } from 'react' 2import { HiChevronDoubleUp } from 'react-icons/hi' 3import IconButton from '../IconButton/IconButton'

必要なライブラリをインポートします。

トップへ戻るボタンの表示・非表示を管理する状態を保持するための useStatescroll 位置を監視するための副作用として useEffect を利用します。

IconButton は自分で作っているアイコンをボタンデザインで表示するコンポーネントです。

状態管理

1const [show, setShow] = useState<boolean>(false)

論理値で表示・非表示を管理します。

表示・非表示を変更する関数

1const PAGE_Y_OFFSET_LIMIT = 200 2 3const changeShow = () => { 4 if (window.pageYOffset > PAGE_Y_OFFSET_LIMIT) { 5 setShow(true) 6 } else { 7 setShow(false) 8 } 9}

DOMwindow オブジェクトから Y 方向(縦方向)のスクロール位置と、定義した Y 方向の境界とする値を比較し、表示・非表示を決める関数を定義します。

定数値なので、他の定数ファイルから読み込むと良いです。

参考:https://developer.mozilla.org/en-US/docs/Web/API/Window/pageYOffset

ページ上部へ遷移する関数

1const onScrollTop = () => { 2 window.scroll({ top: 0, behavior: 'smooth' }) 3}

window オブジェクトの scroll 関数(メソッド)を呼び出してスクロールします。

参考:https://developer.mozilla.org/ja/docs/Web/API/Window/scroll

スクロールを監視する副作用である useEffect

1useEffect(() => { 2 window.addEventListener('scroll', changeShow) 3 return () => window.removeEventListener('scroll', changeShow) 4}, [])

useEffect の第二引数に空の配列を渡して、最初にコンポーネントがマウントされた時に window オブジェクトに scroll イベントを追加します。

return 以降でアンマウント時(コンポーネントを使わなくなるようなこと)に、そのイベントを削除します。

注意点

常にスクロールを監視するのはパフォーマンス上良くない場合がありますので、ご注意ください。

100ms ごとにスクロール監視などで十分かと思います。


また、Internet Explore などの古いブラウザ、Safari ではスムーズ遷移するとは限りません。

その場合は、以下のような Polyfill ライブラリを使ってください。

僕自身は、ページ上部へ戻る時の動きに価値はないと考えています。そのため外部ライブラリを使うことはしません。

https://github.com/wessberg/scroll-behavior-polyfill

他のやり方

無数にありますが、結局やりたいことは同じなので代わり映えしません。

例えば以下の方法があります。

  • react-scroll などのライブラリを用いる
  • a タグで href='#'としページトップへ遷移する

おわりに

以上でこのサイトの右下のようなページ遷移が完成します。

気軽にご自身のサイトに取り入れてみてください。

参考




共有する