Flickering issue with fixed positioning on scroll in React component

I’m encountering a flickering issue in my React component when implementing a fixed positioning effect on scroll. Here’s the scenario:

I have a parent <div> that takes the minimum height of the screen (min-h-screen) and contains three child <div> elements, each taking the full height of the screen (h-screen). The objective is to achieve the following behavior:

  1. When the top of the parent <div> reaches the top of the screen, the first child should be displayed in the viewport.

  2. As the user scrolls, the subsequent children should come into view one after another, with the first child always at the top until the last child is reached.

  3. When the bottom of the parent <div> reaches the bottom of the screen, the parent <div> should move with the scroll and no longer remain fixed.

I’ve implemented this functionality using React hooks (useRef, useState, useEffect) to detect the scroll position and toggle the fixed positioning accordingly. However, I’m encountering a flickering issue specifically when the bottom condition is met.

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

export default function WhatWeDo() {
  const ref = useRef<HTMLDivElement>(null);
  const [isFixed, setIsFixed] = useState(false);

  useEffect(() => {
    const handleScroll = () => {
      if (ref.current) {
        const divTop = ref.current.getBoundingClientRect().top;
        const divBottom = ref.current.getBoundingClientRect().bottom;
        const screenHeight = window.innerHeight;

        if (divTop <= 0 && divBottom >= screenHeight) {
          setIsFixed(true);
        } else if (divTop > 0 || divBottom < screenHeight) {
          setIsFixed(false);
        }
      }
    };

    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);

  return (
    <div
      ref={ref}
      className="w-full min-h-screen flex flex-col bg-gray-50 gap-20 items-start justify-start"
    >
      {/* Background text */}

      <div
        className={`${
          isFixed ? "fixed" : ""
        }  w-full max-h-screen h-screen flex justify-center items-center bg-pink-200 left-0 top-0`}
      >
        <span className="text-8xl font-bold text-black">
          WHAT WE DO {isFixed ? "fixed" : "notfixed"}
        </span>
      </div>

      <div className="w-full h-screen"></div>

      <div className="w-1/2 max-h-screen h-screen flex justify-center items-center bg-blue-200 z-10">
        <span className="text-8xl font-bold text-black">WHAT WE DO 1</span>
      </div>
      <div className="w-1/2 max-h-screen h-screen flex justify-center items-center bg-orange-200 z-10">
        <span className="text-8xl font-bold text-black">WHAT WE DO 2</span>
      </div>
      <div className="w-full h-screen"></div>
    </div>
  );
}