画面を下にスワイプで再読み込みする機能【react-simple-pull-to-refresh】
投稿日: 2025年02月04日
プチ個人開発で作った出費管理アプリで使ったライブラリの紹介です。
「サイトを開いて出費を登録するまで3秒以内に完了できること」
を目的として作ったので、
ホーム画面への追加は必須要件となります。
お会計で「Suicaで」や「Paypayで」と伝えてから
お店のリーダーが起動するまでの待ち時間での入力を想定しています。
また、ゆくゆくはオフライン状態でもローカルでデータを保存して、
オンライン復帰時にデータを同期するようにもしたく、
PWAとして動作させることにしました。
PWAの問題の一つに、”画面上に再読み込みボタンが存在しない”があります。
また、一般的なブラウザにある
”画面を下にスワイプして画面の再読み込み”の仕様もありません。
なので、PWAで動作させる場合、画面の再読み込みをするには
アプリケーション側で再読み込みボタンを設置する
一度アプリを閉じて、再起動する
のどちらかになり、
どちらもユーザーにとっては認知負荷が大きくなります。
また、Webアプリケーションにおいて”画面のリロードができない”は
結構危険な側面もあり、
例えば、新機能のリリースなどで、
バックエンドとフロントエンド両方変更した内容をデプロイした際
バックエンドは即座に反映されますが、
フロントエンドに関しては、画面を再読み込みして、
サーバーにあるHTML/CSS/JSなどの静的ファイルを読み込み直さないと、
新しいバージョンに切り替わりません。
画面の再読み込みをするまでは、
バックエンドとフロントエンドでバージョンがズレている状態となり、
例えばDBのスキーマが変わっている場合などは
APIリクエストでフロントから古いバージョンのリクエストが飛び、
エラーが発生してしまうこともあります。
エラーで止まればまだ良いのですが、
最悪、エラーが起こらずに処理が実行され
その結果、意図しない不整合データが作られてしまう可能性もあります。
これは「リビジョン問題」として、
SPAでフロントエンドとバックエンドを分けて開発するようになった時代特有の問題です。
大規模なプロジェクトなどでは、インシデントになりかねないので、バックエンドにバージョン管理のJSONファイルなどを仕込んでおいて、フロントエンドでバージョン変更を検知したら自動で強制リロードがかかるようにして、対策したりします。
前置きが長くなりましたが、
今回、PWAでも画面の下スワイプで再読み込みする機能を追加しました。
ライブラリがあるので、そちらを使います。(react-simple-pull-to-refresh
)
インストール
npm i react-simple-pull-to-refresh
実装もとてもシンプルです。(layout.tsx
)
import PullToRefresh from "react-simple-pull-to-refresh";
export default function Layout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const handleRefresh = () => {
window.location.reload();
};
return (
<PullToRefresh onRefresh={handleRefresh}>
<div className="p-4">{children}</div>
</PullToRefresh>
);
}
これで、下スワイプ時にonRefresh
が呼ばれ、
ハンドラであるhandleRefresh
でwindow.location.reload();
を行うことで、
画面の再読み込みが行えます。
このライブラリを使うと、
通常のブラウザで使ってスワイプすると2重で再読み込みされる動作になってしまうので、
const isPWA = window.matchMedia('(display-mode: standalone)').matches;
といった形でPWAで動作中かどうかが判別可能なので、
PWA動作中のみPullToRefresh
を使う実装をするのが良さそうです。
PullToRefresh
コンポーネントは他にも、
propsで読み込み中UIもカスタムできたりして、便利ライブラリでした。