useScrollDirection Hook makes slide in button to flicker

Viewed 25

It is quite simple yet annoying to go around. While scrolling down on mobile device, nothing should be happening. But the moment you scroll upwards i am using a Custom Hook to recognise direction and then trigger transition for button to slide in. However, as the screen is still moving, my Hook is still re-rendering and makes my button flicker. It does slide in if the scrolling stopps. I just cant get around this to make it slide in smoothly.

Here is the Hook.

import { useEffect, useState } from "react"

export const SCROLL_UP = "up"
export const SCROLL_DOWN = "down"

export const useScrollDirection = (
  initialDirection = SCROLL_DOWN,
  thresholdPixels = 20
) => {
  const [scrollDir, setScrollDir] = useState(initialDirection)

  useEffect(() => {
    const threshold = thresholdPixels || 0
    let lastScrollY = window.pageYOffset
    let ticking = false

    const updateScrollDir = () => {
      const scrollY = window.pageYOffset

      if (Math.abs(scrollY - lastScrollY) < threshold) {
        // We haven't exceeded the threshold
        ticking = false
        return
      }

      setScrollDir(scrollY > lastScrollY ? SCROLL_DOWN : SCROLL_UP)
      lastScrollY = scrollY > 0 ? scrollY : 0
      ticking = false
    }

    const onScroll = () => {
      if (!ticking) {
        window.requestAnimationFrame(updateScrollDir)
        ticking = true
      }
    }

    window.addEventListener("scroll", onScroll)

    return () => window.removeEventListener("scroll", onScroll)
  }, [initialDirection, thresholdPixels])

  return scrollDir
}
0 Answers
Related