deve.K

エンジニアが未来を切り開く。

English

React Hooks カスタムフック スクロールイベント


スポンサーリンク

オリジナルReactCustomhooksScroll画像

スクロールイベントは、Webページで最もよく使用されるイベントの1つです。

ほとんどの場合では必要なのは『一番上までスクロール』することだけです

長いコンテンツページがありそこに移動すると、下にスクロールされたままになるためとなります。

ですが、その前にReactの『カスタムフック』コンポーネントを作成しスクロールイベントリスナーでユーザーの現在のウィンドウ位置を取得する方法を学ばなければいけません。

本日はその取得方法を解説していきます。

独自(カスタム)フックを作成し簡単な例で学んでいきましょう。

現在のウィンドウ位置を取得

import { useEffect, useState } from "react";
import React from 'react';

const useScroll = () => {

  const [scrollPosition, setScrollPosition] = useState(0);

  useEffect(() => {

    const PositionUp = () => {
      setScrollPosition(window.pageYOffset);
    }

    window.addEventListener("scroll", PositionUp);
    PositionUp();

    return () => window.removeEventListener("scroll", PositionUp);
  }, []);

  return scrollPosition;
};

export default useScroll;

それでは、分割しながら説明していきます。

const useScroll = () => {

  const [scrollPosition, setScrollPosition] = useState(0);

『useScroll』カスタムフックとなります

まずは『scrollposition』のローカル状態で『useState』で初期値をゼロとして作成します。

  useEffect(() => {

    const PositionUp = () => {
      setScrollPosition(window.pageYOffset);
    }

    window.addEventListener("scroll", PositionUp);
    PositionUp();

『useEffect』フック内に『addEventListener』でスクロールイベントを追加し、ユーザーがスクロールするたびに『scrollposition』の初期値である状態を更新します。

状態の変更は『pageYOffset』は、Windowのプロパティで垂直方向のスクロール量となります。

『window 』はブラウザタブになります、なのでタブのスクロールを監視します。

    return () => window.removeEventListener("scroll", PositionUp);
  }, []);

  return scrollPosition;
};

export default useScroll;

『removeEventListener』でコンポーネントをアンマウントしたら、スクロールリスナーをクリア(削除)にするために呼び出し関数を返します。

その後、カスタムフックの下部に最後は『scrollposition』を返します。

作成したフックを任意のファイルにインポートして新しい変数として割り当て、使用していくだけとなります。

import useScroll from "./useSroll";

const App = () => {

const scrollPosition = useScroll();

  console.log(scrollPosition);


return(<div>

</div>)

}

※これはコンポーネントに対してアニメーションを追加する場合に役立つことがあります。

ページ上のDOM要素にアクセスしたい

ページ上のDOM要素にアクセスする為には、当ブログの記事で一度解説したのですが『useRef』を使用する必要があります。

『useRef』に精通がない場合はまず、こちらで学ばれてみて下さい。

dev-k.hatenablog.com

一般的で非常に簡単な例で確認していきましょう。

スクロールイベントリスナーをページの『div』にアクセスします。

import { useRef, useEffect, useCallback } from "react";

const App = () => {

  const ref = useRef();

  const handleScrolling = useCallback(() => {
    console.log("scrolling");

  }, []);

  useEffect(() => {

    const div = ref.current;

    div.addEventListener('scroll', handleScrolling);

  }, [handleScrolling]);

  return (
<div className='App-header'>
    <div className="scrollContainer" ref={ref}>
      <div className="content">
コンソールで確認しながら下にスクロールして下さい。
</div>
      </div>
    </div>
  );
}

既存のApp.cssにスタイルを追加します。

.scrollContainer {
  width: 600px;
  height: 200px;
  overflow-y: auto;
}

.content {
  height: 800px;
}

DEMO

f:id:dev04K:20220107154851g:plain

import React, { useRef, useEffect } from "react";

const App = () => {

  const ref = useRef();

  const handleScrolling = useCallback(() => {
    console.log("scrolling");

  }, []);

『handleScrolling』はスクロールでのイベントリスナーとなります。

  useEffect(() => {

    const div = ref.current;

    div.addEventListener('scroll', handleScrolling);

  }, [handleScrolling]);

副作用フックである2番目の(配列)の依存関係を確認してみると

『handleScrolling』という関数が変更された時のみにフックが実行されます。

この依存関係はフック内で使用していますので自動で追加されていき、つまりこのフックは一度だけ実行されます。

Reactでは現在のスクロール位置を追跡することは非常に困難でもあります、アプリケーションに不要な負荷をかけ、ユーザーエクスペリエンスを劇的に低下させる可能性があることに注意しながら扱うようにして下さい。

ページ内のDOM要素にアクセスする場合には『Refs』の扱い方にも気を付けて下さい。

本日は以上となります。

最後まで読んで頂きましてありがとうございました。

貴方がReactでスクロールイベントを活用時にアプリケーションの構造を考える時、この記事が役に立つ事を願っております。

プライバシーポリシー