import { useEffect, useRef, useState } from 'react' /** * useInView 判断元素是否进入视口(默认提前 200px 触发)。 * * 用途:分析页里"按应用统计"这类必须读日志内容的查询很贵(实测大集群 * 15 分钟约 20~30 秒)。一次性全查会让首屏一起等,用户看到的是整页转圈。 * 改成滚动到该卡片附近才发查询:上面的总量/趋势先出来,下面的慢数据后补。 * * 只触发一次(进入视口后断开监听):日志分析是只读快照,不需要来回重算。 */ export function useInView(rootMargin = '200px') { const ref = useRef(null) const [inView, setInView] = useState(false) useEffect(() => { if (inView) return const el = ref.current if (!el) return // 老浏览器/SSR 环境没有 IntersectionObserver:直接当作可见,别把功能卡死 if (typeof IntersectionObserver === 'undefined') { setInView(true) return } const observer = new IntersectionObserver( entries => { if (entries.some(entry => entry.isIntersecting)) { setInView(true) observer.disconnect() } }, { rootMargin }, ) observer.observe(el) return () => observer.disconnect() }, [inView, rootMargin]) return { ref, inView } }