简体   繁体   中英

Unobserve IntersectionObserver in React.useEffect

I am trying to get the top and bottom measurements from multiple elements by using IntersectionObserver . However, once I have the measurements, how can I unobserve the elements.

The problem is that each element is position: sticky and when scrolling additional values are added to the array and I only want the measurements from the initial render.

const observer = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      const measurement = {
        top: entry.boundingClientRect.top,
        bottom: entry.boundingClientRect.bottom,
      };
      console.log(measurement);
    });
  });

  useEffect(() => {
    const sections = document.querySelectorAll(`section#dark`)
    sections.forEach((section) => observer.observe(section));
    return () => {
      // observer.disconnect(); removed in Stackoverflow edit
      sections.forEach(section => observer.observe(section)); // Added in Stackoverflow edit
    };
  }, []);

I have tried using observer.unobserve() but cannot figure out what value it requires as it returns an error of Argument of type 'NodeListOf<Element>' is not assignable to parameter of type 'Element'.

EDIT: I figured out how to use oberver.unobserve with sections.forEach(section => observer.unobserve(section)); but it still adds more records when scrolling.

Full example can be seen here StackBlitz

You need to move the observer instance to useEffect block because every time your component is updated a new IntersectionObserver instance is created:

useEffect(() => {
  const observer = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
      const measurement = {
        top: entry.boundingClientRect.top,
        bottom: entry.boundingClientRect.bottom,
      };
      console.log(measurement);
      observer.unobserve(entry.target); //<-- call unobserve here
      });
    });
  const sections = document.querySelectorAll(`section#dark`)
  sections.forEach((section) => observer.observe(section));
  return () => {
     observer.disconnect();
  };
}, []);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM