我正在尝试使用React/Hooks和交叉点观察者API来跟踪元素可见性。但是,我不知道如何使用"useEffect“设置观察值。有人知道我是怎么做到的吗?我的解决方案不起作用..。
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>
);
}发布于 2019-10-14 18:04:05
需要使用React.useRef()而不是addEventListener('load',function() ),因为eventListener会在某些东西出现在屏幕上之前运行。
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>
);
}发布于 2020-11-18 19:59:04
这是一个可重用的钩子,它使用ref和useEffect清理功能来防止在挂载/卸载大量组件时发生内存泄漏
钩子
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
}组件中的用法
function DumbComponent() {
const ref = useRef()
const onScreen = useOnScreen(ref)
return <div ref={ref}>{onScreen && "I'm on screen!"}</div>
}发布于 2021-06-04 01:27:10
JavaScript
钩子
import { useEffect, useState, useRef } from 'react';
export function useOnScreen(ref) {
const [isOnScreen, setIsOnScreen] = useState(false);
const observerRef = useRef(null);
useEffect(() => {
observerRef.current = new IntersectionObserver(([entry]) =>
setIsOnScreen(entry.isIntersecting)
);
}, []);
useEffect(() => {
observerRef.current.observe(ref.current);
return () => {
observerRef.current.disconnect();
};
}, [ref]);
return isOnScreen;
}用法:
import { useRef } from 'react';
import useOnScreen from './useOnScreen';
function MyComponent() {
const elementRef = useRef(null);
const isOnScreen = useOnScreen(elementRef);
console.log({isOnScreen});
return (
<div>
<div style={{ paddingBottom: '140vh' }}>scroll to element...</div>
<div ref={elementRef}>my element</div>
</div>
);
}TypeScript
钩子
import { useEffect, useState, useRef, RefObject } from 'react';
export default function useOnScreen(ref: RefObject<HTMLElement>) {
const observerRef = useRef<IntersectionObserver | null>(null);
const [isOnScreen, setIsOnScreen] = useState(false);
useEffect(() => {
observerRef.current = new IntersectionObserver(([entry]) =>
setIsOnScreen(entry.isIntersecting)
);
}, []);
useEffect(() => {
observerRef.current.observe(ref.current);
return () => {
observerRef.current.disconnect();
};
}, [ref]);
return isOnScreen;
}用法:
import { useRef } from 'react';
import useOnScreen from './useOnScreen';
function MyComponent() {
const elementRef = useRef<HTMLDivElement>(null);
const isOnScreen = useOnScreen(elementRef);
console.log({isOnScreen});
return (
<div>
<div style={{ paddingBottom: '140vh' }}>scroll to element...</div>
<div ref={elementRef}>my element</div>
</div>
);
}https://codesandbox.io/s/useonscreen-uodb1?file=/src/useOnScreen.ts
https://stackoverflow.com/questions/58341787
复制相似问题