The Intersection Observer does not call a callback in react

36 views Asked by At

My component is a window with a hint. Its location is indicated in prop ___ . I want to implement a window visibility check with a hint. If the tooltip is partially closed in the current position, then move it to the next position from the WINDOWPOSITIONS array. The error is that when the tooltip is rendered in a position where it is fully visible, callback is not called and the state of isVisible does not change to true;

const OPTIONS: OptionsObserverI = { threshold: 1 };

const WINDOWPOSITIONS: WindowPositionT[] = [
  'top',
  'left',
  'right',
  'bottom',
  'top-right',
  'top-left',
  'bottom-right',
  'bottom-left',
];

const ObserverWatcher = ({ options, callback, refWatched }) => {
  useEffect(() => {
    const observer = new IntersectionObserver(callback, options);
    if (refWatched.current !== null) {
      observer.observe(refWatched.current);
    }

    const node = refWatched.current;
    return () => {
      if (node && observer) observer.disconnect();
    };
  }, [callback, options, refWatched]);

  return null;
};

export default function HintWindow(props: PropsI) {
  const { color, text, title, classes, hookRefButton, windowPosition } = props;
  const windowRef = useRef<HTMLDivElement | null>(null);
  const [positionState, setPositionState] = useState<WindowPositionT | 'default'>(windowPosition);

  const [isVisible, setIsVisible] = useState(true);
  const refWatched = useRef<HTMLElement | null>(null);
  const callback = useCallback((entries) => {
    const entry = entries[entries.length - 1];
    setIsVisible(entry.isIntersecting);
  }, []);

  const setRef = (element: HTMLDivElement) => {
    refWatched.current = element;
    windowRef.current = element;
  };

  
  const arrRef = useRef<(WindowPositionT | 'default')[] | null>(null);
  const stopRef = useRef(false);

  useLayoutEffect(() => {
    if (!isVisible && arrRef.current === null) {
      arrRef.current = [...WINDOWPOSITIONS];
      const n = arrRef.current.indexOf(positionState);
      const temp = arrRef.current.splice(0, n + 1);
      temp.pop();
      arrRef.current = [...arrRef.current, ...temp];
    }

    if (!isVisible && arrRef.current !== null) {
      if (arrRef.current.length > 0) {
        setPositionState(arrRef.current[0]);
        arrRef.current.splice(0, 1);
      } else if (arrRef.current.length === 0 && !stopRef.current) {
        setPositionState('default');
        stopRef.current = true;
      }
    }
  }, [isVisible, positionState, refWatched]);

  return (
    <>
      {createPortal(
        <Window
          key={positionState}
          {...props}
          setRef={setRef}
          topWindow={topWindow}
          leftWindow={leftWindow}
          positionState={positionState}
        />,
        document.body,
      )}
      <ObserverWatcher options={OPTIONS} callback={callback} refWatched={refWatched} />
    </>
  );
}

For what reason should callback not be called if the prompt window becomes visible

0

There are 0 answers