
【React】ページ上部では表示しないトップへ戻るボタンを作る【外部ライブラリなし】
2022-04-22
2022-04-22
はじめに
こんにちは!ブックマークしたサイトをやっと整理したこふです。
この記事では、本ブログの右下にもある「ページの一番上へ戻るボタン」の作り方を解説します。

注意 ❗
以下の実装がベストプラクティスとは限りませんので、あくまで参考になさってください。
環境
React
以外の外部ライブラリは当然用いません。当然、Next.js
や Gatsby.js
に組み込めます。
1❯ node -v 2v16.14.0
アイコンは各自で svg
ファイルを読み込む・書き込むで対応 OK です
package.json1{ 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.tsx1import { 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'
必要なライブラリをインポートします。
トップへ戻るボタンの表示・非表示を管理する状態を保持するための useState
、scroll
位置を監視するための副作用として 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}
DOM
の window
オブジェクトから 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='#'
としページトップへ遷移する
おわりに
以上でこのサイトの右下のようなページ遷移が完成します。
気軽にご自身のサイトに取り入れてみてください。