使用 Intersection Observer 在 ReactJS 中实现数据懒加载
无滚动事件
useLazyLoad钩
onIntersect
triggerRef
工作演示
延迟加载是指网站无需用户点击按钮即可加载新数据供用户查看的一种方式。
无滚动事件
许多关于懒加载的教程都使用滚动事件来判断用户是否滚动到了容器的末尾。使用滚动事件确实是一种有效的解决方案,但我正在考虑一种替代方案。
欢迎来到交叉点观察器 API。交叉点观察器会跟踪元素何时与给定容器相交。我们将使用它来判断是否已到达容器底部。
useLazyLoad钩
useLazyLoad我们将在钩子函数中使用交叉观察器。该钩子函数将有 3 个参数—— triggerRef,,onGrabData和options。
triggerRef是我们的触发元素的引用onGrabData是将要调用以加载更多数据的函数。options是可以传递给 Intersection Observer 构造函数的选项对象。
const useLazyLoad = (triggerRef, onGrabData, options) => {
...
}
在内部useEffect,我们将创建观察者。
useEffect(() => {
if (triggerRef.currrent) {
const observer = new IntersectionObserver(onIntersect, options)
observer.observe(triggerRef.current)
return () => {
observer.disconnect()
}
}
}, [triggerRef, onIntersect, options])
这里需要注意两点重要事项:onIntersect,observe()和disconnect()。
onIntersect是观察者在被观察元素与观察者根交互时调用的回调函数。observe这是一个使元素成为观察者应该跟踪的对象的功能。disconnect是一个清理函数,用于停止观察者进行观察。
onIntersect
交叉路口观察器所需的回调函数接收entries作为其参数。
const onIntersect = (entries) => {
const boundingRect = entries[0].boundingClientRect
const intersectionRect = entries[0].intersectionRect
if (intersectionRect.bottom - boundingRect.bottom <= 5) {
onGrabData(...)
}
}
entries
该参数是一个IntersectionObserverEntryentries数组。当一个或多个被观察的元素与该数组相交或停止相交时,将调用回调函数。root
triggerRef
这triggerRef是交叉观察器将要跟踪的一个元素。
...
const triggerRef = useRef(null)
const { data } = useLayLoad(triggerRef, onGrabData, options)
...
return (
<section>
{data.map((item) => (
<div key={item.id}>
...
</div>
))}
<div ref={triggerRef} />
</section>
)
...
触发元素位于数据下方,数据会将触发元素推到视口之外。当用户向下滚动时,触发元素将与视口相交,从而触发相交观察器回调。