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

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

2022-04-22

2022-04-22

はじめに

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

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


注意 ❗

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


環境

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

node -v v16.14.0

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

package.json
{ "dependencies": { ... "react": "^17.0.2", "react-dom": "^17.0.2", "react-icons": "^4.3.1", ... }, "devDependencies": { ... "autoprefixer": "^10.4.0", "postcss": "^8.4.5", "tailwindcss": "^3.0.7", "typescript": "4.5.4" ... } }

ソースコード

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

ScrollToTop.tsx
import { useEffect, useState } from 'react' import { HiChevronDoubleUp } from 'react-icons/hi' import IconButton from '../IconButton/IconButton' const PAGE_Y_OFFSET = 200 const ScrollToTop = () => { const [show, setShow] = useState<boolean>(false) const changeShow = () => { if (window.pageYOffset > PAGE_Y_OFFSET) { setShow(true) } else { setShow(false) } } const onScrollTop = () => { window.scroll({ top: 0, behavior: 'smooth' }) } useEffect(() => { window.addEventListener('scroll', changeShow) return () => window.removeEventListener('scroll', changeShow) }, []) if (show) return ( <div className="fixed bottom-10 right-10 z-10"> <IconButton Icon={HiChevronDoubleUp} onClick={onScrollTop} /> </div> ) else return null } export default ScrollToTop

ソースコードの解説

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

ライブラリ群

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

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

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

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

状態管理

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

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

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

const PAGE_Y_OFFSET_LIMIT = 200 const changeShow = () => { if (window.pageYOffset > PAGE_Y_OFFSET_LIMIT) { setShow(true) } else { setShow(false) } }

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

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

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

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

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

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

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

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

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

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

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

注意点

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

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


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

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

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

他のやり方

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

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

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

さいごに

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

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

参考



アバター

こふ

情報通信を専攻している大学生です。大学(研究)・趣味・アルバイトでプログラムを書いています。ITツール・サービス・文章を創作することが好きです。

ぼくについて

共有する