在 React.useEffect 中取消观察 IntersectionObserver

Unobserve IntersectionObserver in React.useEffect

我正在尝试使用 IntersectionObserver 从多个元素中获取 topbottom 测量值。但是,一旦我有了测量值,我怎么才能 unobserve 元素。

问题是每个元素都是 position: sticky 并且当滚动时附加值被添加到 array 而我只想要来自初始渲染的测量值。

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 Whosebug edit
      sections.forEach(section => observer.observe(section)); // Added in Whosebug edit
    };
  }, []);

我试过使用 observer.unobserve() 但无法弄清楚它需要什么值,因为它 returns 是 Argument of type 'NodeListOf<Element>' is not assignable to parameter of type 'Element'.

的错误

编辑:我想出了如何将 oberver.unobservesections.forEach(section => observer.unobserve(section)); 一起使用,但它在滚动时仍会添加更多记录。

完整的例子可以在这里看到StackBlitz

您需要将观察者实例移动到 useEffect 块,因为每次更新组件时都会创建一个新的 IntersectionObserver 实例:

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();
  };
}, []);