skip to Main Content

I’m experiencing an issue with the useDetectScroll hook from @smakss/react-scroll-direction in my React component. When I make my element sticky using position: sticky, the useDetectScroll hook gets triggered in an infinite loop, which causes the element that should hide on scroll to flicker.

Here is my code:

"use client";
import clsx from "clsx";
import useDetectScroll, { Direction } from "@smakss/react-scroll-direction";

const Page = () => {
  const { scrollDir } = useDetectScroll();

  return (
    <>
      <header className="bg-white w-full sticky top-0">
        <div className="container mx-auto flex items-center justify-between bg-red-500">
          Content
        </div>

        <div
          className={clsx(
            scrollDir === Direction.Still || scrollDir === Direction.Up
              ? "block"
              : "hidden",
            "container mx-auto bg-blue-500 flex items-center"
          )}
        >
          Hide on scroll
        </div>
      </header>

      <div className="h-[2048px] container mx-auto">Page content</div>
    </>
  );
};

export default Page;

Problem:

When scrolling, the scrollDir state seems to toggle continuously between Direction.Still and Direction.Up, which leads to the .hidden class being applied and removed repeatedly. As a result, the Hide on scroll div flickers instead of remaining hidden or visible as expected.

If I change the element to position: fixed and adjust the padding of the rest of the page content based on the header’s height, the issue goes away. However, I’d prefer to avoid this solution if possible.

Question:

Why does making the element sticky cause useDetectScroll to enter an infinite loop, and how can I prevent this behavior to ensure the element correctly hides or shows based on the scroll direction without resorting to using position: fixed?

2

Answers


  1. Chosen as BEST ANSWER

    I was able to solve this using transform

    <div className={clsx((scrollDir === Direction.Still || scrollDir === Direction.Up) ? "translate-y-0" : "-translate-y-full")}>
      Hide on scroll!! {scrollDir}
    </div>
    

  2. try to use it without 3 display parameters, I think it should work.

    className={cn("container mx-auto bg-blue-500 flex items-center", {
                hidden: scrollDir === Direction.Still || scrollDir === Direction.Up,
              })}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search