はじめに
Reactで無限スクロールしたい時にスクロール終了イベントを検知したい時があったので、その方法をメモとして残す。
スクロールライブラリはたくさんあるようなので、使用するライブラリを不用意に増やしたくない場合などに参考になれば。
サンプルプログラム
挙動
ベースのリストを用意してスクロールが終了したタイミングで、表示させるリストにベースのリストを追加し続ける。
コード
index.tsx
import type { SyntheticEvent } from 'react';
import { useEffect, useState } from 'react';
export default function Index() {
const [list, setList] = useState<string[]>([]);
const baseList = [
'Japan',
'United States',
'Canada',
'Mexico',
'Argentina',
'Brazil',
'France',
'Germany',
'Italy',
'Spain',
'United Kingdom',
'Russia',
'China',
'India',
'Indonesia',
'Thailand',
'Australia',
'New Zealand',
'South Africa',
'Egypt',
'Nigeria',
'Kenya',
'Ethiopia',
'Ghana',
'Morocco',
'Tunisia',
'Saudi Arabia',
'Iran',
'Iraq',
'Israel',
'Turkey',
];
/**
* 高さを計算してスクロールの最後まで来ていたら、リストを追加する
*/
const addList = (event: SyntheticEvent) => {
const currentTarget = event.currentTarget;
if (currentTarget.scrollHeight === currentTarget.scrollTop + currentTarget.clientHeight) {
setList([...list, ...baseList]);
}
};
useEffect(() => {
setList(baseList);
}, []);
return (
<main style={{ height: '100vh' }}>
<ul style={{ overflowY: 'scroll', height: '100%' }} onScroll={addList}>
{list.map((value, index) => {
return (
<li key={value + index} style={{ height: 50 }}>
{index + ' - ' + value}
</li>
);
})}
</ul>
</main>
);
}
説明
スクロールしている要素のonScrollイベントにてスクロール位置を取得することができる。
ここから、高さを計算しスクロールが終了しているかを判断する。終了していればリストを追加する。
スクロールが終了する前に追加リストを取得したい場合などは、高さの計算時にマージンを追加して対応する。
デモ
参考