deve.K

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

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

オリジナルReactCustomhooksScroll画像

スクロールイベント

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

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

長いコンテンツページがありそこに移動すると、下にスクロールされたままになり、一番上に戻るのが非常に面倒になるためです。

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

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

Reactフックでカスタムフックを作成し、再利用可能なコンポーネントにします。

それでは簡単な例で学んでいきましょう。

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

// useScroll.js

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;

下記のcodepenでコンソールの出力を確認下さい。

https://codepen.io/enjinia_f/pen/dymNPrV/?editors=1011

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

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』でコンポーネントをアンマウントしたら、スクロールリスナーをクリア(削除)にするために呼び出し関数を返します。

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

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

// App.js

import useScroll from "./useSroll";

const App = () => {

const scrollPosition = useScroll();

  console.log(scrollPosition);


return(<div>

</div>)

}

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

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

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

useRefフックに精通がない場合はまず、下記で学ばれてみて下さい。

dev-k.hatenablog.com

useCallbackフックも使用します。

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

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

// App.js

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にスタイルを追加します。

/* App.css  */

.scrollContainer {
  background-color: rgba(0, 0, 0, 0.8);
  color: #fff;
  border: 3px solid black;
  width: 400px;
  height: 100px;
  overflow: scroll;

}

.content {
  height: 800px;
}

DEMO

実際の出力は下記で確認できます。

https://codepen.io/enjinia_f/pen/MWVJYZW/?editors=1011

// App.js

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

const App = () => {

  const ref = useRef();

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

  }, []);

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

// App.js

  useEffect(() => {

    const div = ref.current;

    div.addEventListener('scroll', handleScrolling);

  }, [handleScrolling]);

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

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

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

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

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

本日は以上となります。

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

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

プライバシーポリシー