Observe an element's entry in viewport once with IntersectionObserver in React

Viewed 40

I'm using a function to animate elements when getting into viewport but I would like to change it so it will do it only once...I/m not sure how/where to edit to accomplish this...any advice?

function useIsInViewport(ref) {
  const [isIntersecting, setIsIntersecting] = useState(false);

  const observer = useMemo(
    () =>
      new IntersectionObserver(([entry]) =>
        setIsIntersecting(entry.isIntersecting),
      ),
    [],
  );

  useEffect(() => {
    observer.observe(ref.current);

    return () => {
      observer.disconnect();
    };
  }, [ref, observer]);

  return isIntersecting;
}

On page I use a const for setting:

const ref1 = useRef(null);
const isInViewport1 = useIsInViewport(ref1);

Then setting a class on the element:

${isInViewport1 && "fadeInDown"}
1 Answers

You need to call observer.unobserve(entry.target) after the first iteration. Like below in in your specific case:

function useIsInViewport(ref) {
  const [isIntersecting, setIsIntersecting] = useState(false);

  const observer = useMemo(
    () =>
      new IntersectionObserver(([entry]) => {
        setIsIntersecting(entry.isIntersecting);
        observer.unobserve(entry.target); // line I added
      }),
    []
  );

  useEffect(() => {
    observer.observe(ref.current);

    return () => {
      observer.disconnect();
    };
  }, [ref, observer]);

  return isIntersecting;
}
Related