IntersectionObserver with React & Hooks

一个人想着一个人 提交于 2021-01-19 06:27:14

问题


I'm trying to track element visibility with React/Hooks and the Intersection Observer API. However, I can't figure out how to set up observation with "useEffect". Does anybody have any idea how could I do that? Mine solution does not work...

function MainProvider({ children }) {
  const [targetToObserve, setTargetToObserve] = useState([]);

  window.addEventListener("load", () => {
    const findTarget = document.querySelector("#thirdItem");
    setTargetToObserve([findTarget]);
  });

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.intersectionRatio === 0.1) {
          console.log("It works!");
        }
      },
      {
        root: null,
        rootMargin: "0px",
        threshold: 0.1
      }
    );
    if (targetToObserve.current) {
      observer.observe(targetToObserve.current);
    }
  }, []);

  return (
    <main>
     <div className="Section-item" id="firstItem"></div>
     <div className="Section-item" id="secondItem"></div>
     <div className="Section-item" id="thirdItem"></div>
    </main>
  );
}

回答1:


Need to use React.useRef() instead of addEventListener('load', function() ), since eventListener will run before something will appear on your screen.

import React, { useRef, useEffect } from 'react'

function MainProvider({ children }) {
  const ref = useRef();

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => {
        console.log(entry);

        if (entry.isIntersecting) {
          //do your actions here
          console.log('It works!')
        }
      },
      {
        root: null,
        rootMargin: "0px",
        threshold: 0.1
      }
    );
    if (ref.current) {
      observer.observe(ref.current);
    }
  }, [ref]);

  return (
    <main>
     <div className="Section-item" id="firstItem"></div>
     <div className="Section-item" ref={ref} id="secondItem"></div>
     <div className="Section-item" id="thirdItem"></div>
    </main>
  );
}



回答2:


Here is a reusable hook that is using ref and useEffect cleanup function to prevent memory leakage whan mounting / unmounting large amount of components

The hook

function useOnScreen(ref) {

  const [isIntersecting, setIntersecting] = useState(false)

  const observer = new IntersectionObserver(
    ([entry]) => setIntersecting(entry.isIntersecting)
  )

  useEffect(() => {
    observer.observe(ref.current)
    return () => {
      observer.disconnect()
    }
  }, [])

  return isIntersecting
}

Usage in a component

function DumbComponent() {

  const ref = useRef()

  const onScreen = useOnScreen(ref)

  return <div ref={ref}>{onScreen && "I'm on screen!"}</div>
}


来源:https://stackoverflow.com/questions/58341787/intersectionobserver-with-react-hooks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!