React scroll direction


This post goes over how to get the scroll direction with React.

useScrollDirection

Create a hook that compares the previous scrollY value to get the scroll direction:

// useScrollDirection.ts
import { useCallback, useEffect, useRef, useState } from 'react';

export enum ScrollDirection {
  'up' = 'up',
  'down' = 'down',
}

export function useScrollDirection() {
  const scrollYRef = useRef(0);
  const [direction, setDirection] = useState(ScrollDirection.up);

  const scrollDirection = useCallback(() => {
    setDirection(
      window.scrollY > scrollYRef.current
        ? ScrollDirection.down
        : ScrollDirection.up,
    );

    scrollYRef.current = window.scrollY;
  }, []);

  useEffect(() => {
    window.addEventListener('scroll', scrollDirection);

    return () => {
      window.removeEventListener('scroll', scrollDirection);
    };
  }, [scrollDirection]);

  return direction;
}

To use the hook:

// App.tsx
import { useScrollDirection } from './useScrollDirection';

function App() {
  const scrollDirection = useScrollDirection();

  return (
    <p>
      Scroll direction: {scrollDirection}
      {/* ... */}
    </p>
  );
}

onWheel

Alternatively, you can use the wheel event but it has limited availability:

// App.tsx
function App() {
  return (
    <div
      onWheel={(event) => {
        event.deltaY > 0 ? console.log('down') : console.log('up');
      }}
    >
      {/* ... */}
    </div>
  );
}

Demo

StackBlitz:



Please support this site and join our Discord!