0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Reactでスクロール方向を検知する超シンプルなカスタムフック

Last updated at Posted at 2025-04-20

Reactでスクロール方向を検知するhooksについて紹介・解説をします。

結論のコード

export type ScrollDirection = 'up' | 'down';

export const useScrollDirection = (
  initialDirection: ScrollDirection = 'up',
) => {
  const [scrollDirection, setScrollDirection] =
    useState<ScrollDirection>(initialDirection);

  useEffect(() => {
    const bodyElement = document.querySelector('body');
    if (!bodyElement) return;

    const onWheel = (e: WheelEvent) => {
      // 不要な更新を防ぐ
      if (e.deltaY < 0 && scrollDirection === 'up') return;
      if (e.deltaY > 0 && scrollDirection === 'down') return;

      if (e.deltaY < 0) setScrollDirection('up');
      if (e.deltaY > 0) setScrollDirection('down');
    };

    bodyElement.addEventListener('wheel', onWheel, { passive: true });
    return () => bodyElement.removeEventListener('wheel', onWheel);
  }, []);

  return scrollDirection;
};

スクロール方向が'up''down'かを返す単純なhooksです。
現在のスクロール位置がたとえページのスクロールし切った下端であっても上方向へのスクロールを検知してScrollDirectionの値を変更させることができます。

レイアウトシフトが発生してもバグのでにくい状態にするため、wheelイベントのdeltaY値を使うようにしています。

不要なsetStateを防ぐためのコードも思いつきで書いた割にかなりコスパよくイベントを抑えてくれます。

使用例

const Header = () => {
  const scrollDirection = useScrollDirection();

  return (
    <header
      style={{
        position: 'fixed',
        top: 0,
        transition: 'transform 0.3s',
        transform: scrollDirection === 'down' ? 'translateY(-100%)' : 'translateY(0)',
      }}
    >
      My Awesome Header
    </header>
  );
};

スクロールを検知してheaderのスタイルを変化させることができます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?