react-visibility-sensorとは
react-visibility-sensor は、そのコンポーネントがブラウザの表示領域に入っているかをチェックしてくれるライブラリです。
このライブラリを使うことで、ブラウザ上で見えている場合にだけ、動作するコンポーネントを作ることができます。
サンプル: https://github.com/geekduck/visibility-sensor-sample
デモ1
コンポーネントが表示領域内(白色の領域)に存在している場合にだけ、
タイマーで現在時刻を更新するコンポーネントを作ってみました。
サンプルコード
コンポーネントが表示領域に出たり入ったりするたびに、VisibilitySensor
のonChange
に渡した関数が実行されます。
const CurrentTimer = () => {
const [currentTime, setCurrentTime] = useState(new Date());
const [timerId, setTimerId] = useState(0);
useEffect(() => {
return () => clearInterval(timerId); // タイマーの後始末
}, [timerId]);
const onChange = (isVisible) => {
if (isVisible) {
// このコンポーネントが表示されている場合、タイマーで現在時刻を更新する。
setTimerId(setInterval(() => {
setCurrentTime(new Date());
}, 10));
} else {
// このコンポーネントが表示されていない場合、タイマーを削除して現在時刻を更新しない。
clearInterval(timerId);
setTimerId(undefined);
}
};
return (
<VisibilitySensor
onChange={onChange} // コンポーネントの表示状態が変わるたびに実行される
partialVisibility={true} // 表示領域にちょっとでも入っていたらisVisible=trueと判定させる。
offset={{top: 100, bottom: 100}} // 見た目でわかりやすいように、上下100pxの範囲は表示領域外にする。
>
<div className="CurrentTimer">{dayjs(currentTime).format('YYYY/MM/DD HH:mm:ss.SSS')}</div>
</VisibilitySensor>
);
};
デモ2
VisibilitySensor
コンポーネントの子要素として、関数を渡すこともできます。
return (
<VisibilitySensor
onChange={onChange} // コンポーネントの表示状態が変わるたびに実行される
partialVisibility={true} // 表示領域にちょっとでも入っていたらisVisible=trueと判定させる。
offset={{top: 100, bottom: 100}} // 見た目でわかりやすいように、上下100pxの範囲は表示領域外にする。
>
{
({isVisible}) => isVisible
? <div className="CurrentTimer">{dayjs(currentTime).format('YYYY/MM/DD HH:mm:ss.SSS')}</div>
: <div className="CurrentTimer"/> // 表示されていない場合は、子要素を表示しない。
}
</VisibilitySensor>
);
この場合、関数の引数としてisVisible
が取得できるので、
表示されていない場合は空のdiv
要素を表示して、renderの負荷を下げるコードが書けます。
類似のライブラリ
表示領域外のコンポーネントをrenderしないライブラリとして有名なものは、react-windowや、react-virtualizedがあります。
大量のコンポーネントをリスト形式で表示する際は、これらのライブラリを使う方が適切です。
参考