问题
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