parcelpanel-polling-checker
v1.1.0
Published
React Hooks for visibility tracking and global object detection
Maintainers
Readme
React Hooks - Cross-sell 可见性检测工具
概述
React Hooks工具集提供了智能化的全局对象检测和可见性跟踪功能,专门用于与Cross-sell Tracking SDK配合使用。
🔧 可用的Hooks
1. useSmartVisibleCrossSellTracker (推荐)
智能可见性跟踪器,具有以下特性:
- ✅ 自动检测元素初始可见性
- ✅ 智能曝光检测(避免不必要的Observer创建)
- ✅ 自动等待CrossSellTracker初始化
- ✅ 防重复触发机制
import { useSmartVisibleCrossSellTracker } from "@packages/polling-checker"
const SmartCard = () => {
const { ref, reset } = useSmartVisibleCrossSellTracker({
onViewed: () => {
console.log("智能检测:元素已曝光!")
window.crossSellTracker?.logViewed("smart-uuid")
},
enabled: true,
rootMargin: "0px",
threshold: 0.5 // 50%可见时触发
})
return (
<div ref={ref} className="smart-card">
<h3>智能推荐卡片</h3>
<button onClick={reset}>重置状态</button>
</div>
)
}2. useVisibleCrossSellTracker
基础可见性跟踪器:
- ✅ 标准IntersectionObserver功能
- ✅ 自动等待CrossSellTracker初始化
- ✅ 支持自定义配置
import { useVisibleCrossSellTracker } from "@packages/polling-checker"
const BasicCard = () => {
const { ref, reset } = useVisibleCrossSellTracker({
onViewed: () => {
window.crossSellTracker?.logViewed("basic-uuid")
},
enabled: true,
threshold: 0.1, // 10%可见时触发
rootMargin: "50px" // 提前50px触发
})
return <div ref={ref}>基础跟踪内容</div>
}3. useCrossSellTracker
CrossSellTracker专用加载检测器:
- ✅ 等待全局CrossSellTracker对象加载
- ✅ 300ms检测间隔,最多5次重试
- ✅ 简化的API
import { useCrossSellTracker } from "@packages/polling-checker"
const TrackerListener = () => {
useCrossSellTracker(() => {
console.log("CrossSellTracker已加载!")
// 可以安全使用tracker了
window.crossSellTracker?.logViewed("ready-uuid")
}, true) // enabled
return <div>等待CrossSellTracker初始化...</div>
}4. useGlobalObjectChecker
通用全局对象检测器:
- ✅ 检测任意全局对象
- ✅ 自定义检测配置
- ✅ 错误重试机制
import { useGlobalObjectChecker } from "@packages/polling-checker"
const GlobalChecker = () => {
const { reset } = useGlobalObjectChecker({
globalKey: "MyGlobalObject",
onReady: () => {
console.log("全局对象已加载!")
},
enabled: true
})
return <div>等待全局对象加载...</div>
}📖 详细配置选项
SmartVisibleCrossSellTracker 配置
interface UseSmartVisibleCrossSellTrackerOptions {
onViewed: () => void // 可见时的回调函数
enabled?: boolean // 是否启用(默认true)
rootMargin?: string // 根边距(默认"0px")
threshold?: number // 可见阈值(默认0.1)
}VisibleCrossSellTracker 配置
interface UseVisibleCrossSellTrackerOptions {
onViewed: () => void // 可见时的回调函数
enabled?: boolean // 是否启用(默认true)
rootMargin?: string // 根边距(默认"0px")
threshold?: number // 可见阈值(默认0.1)
}GlobalObjectChecker 配置
interface UseGlobalObjectCheckerOptions {
globalKey: string // 全局对象的键名
onReady: () => void // 对象加载完成后的回调
enabled?: boolean // 是否启用(默认true)
}🚀 实际使用场景
场景1:推荐卡片列表
import { useSmartVisibleCrossSellTracker } from "@packages/polling-checker"
const RecommendationList = ({ items }) => {
return (
<div className="recommendation-list">
{items.map(item => (
<RecommendationCard
key={item.id}
item={item}
locationUuid={item.trackingUuid}
/>
))}
</div>
)
}
const RecommendationCard = ({ item, locationUuid }) => {
const { ref } = useSmartVisibleCrossSellTracker({
onViewed: () => {
// 自动上报曝光事件
window.crossSellTracker?.logViewed(locationUuid)
},
threshold: 0.6 // 60%可见时触发
})
const handleClick = () => {
// 点击时上报
window.crossSellTracker?.logClicked(locationUuid)
}
return (
<div ref={ref} className="card" onClick={handleClick}>
<img src={item.image} alt={item.title} />
<h3>{item.title}</h3>
<p>{item.description}</p>
</div>
)
}场景2:分步加载检测
import { useCrossSellTracker } from "@packages/polling-checker"
import { useState } from "react"
const StepByStepTracker = () => {
const [step, setStep] = useState(1)
// 第一步:等待CrossSellTracker加载
useCrossSellTracker(() => {
console.log("步骤1:CrossSellTracker已加载")
setStep(2)
}, step === 1)
// 第二步:初始化应用
useEffect(() => {
if (step === 2) {
window.crossSellTracker?.initApp({
shopify_id: 123456,
user_id: 789,
domain: "store.myshopify.com",
plan: "premium",
shopify_version: "2024-01"
}).then(() => {
console.log("步骤2:应用初始化完成")
setStep(3)
})
}
}, [step])
return (
<div>
<p>当前步骤: {step}</p>
{step === 1 && <p>等待CrossSellTracker加载...</p>}
{step === 2 && <p>正在初始化应用...</p>}
{step === 3 && <p>初始化完成,可以开始跟踪!</p>}
</div>
)
}场景3:条件性跟踪
import { useSmartVisibleCrossSellTracker } from "@packages/polling-checker"
import { useState } from "react"
const ConditionalTracker = ({ shouldTrack, locationUuid }) => {
const [hasTracked, setHasTracked] = useState(false)
const { ref, reset } = useSmartVisibleCrossSellTracker({
onViewed: () => {
if (!hasTracked) {
window.crossSellTracker?.logViewed(locationUuid)
setHasTracked(true)
}
},
enabled: shouldTrack && !hasTracked
})
const handleReset = () => {
setHasTracked(false)
reset()
}
return (
<div ref={ref} className="conditional-tracker">
<p>跟踪状态: {hasTracked ? "已跟踪" : "未跟踪"}</p>
<p>跟踪开关: {shouldTrack ? "开启" : "关闭"}</p>
<button onClick={handleReset}>重置跟踪</button>
</div>
)
}⚡ 性能优化特性
智能检测机制
useSmartVisibleCrossSellTracker 的智能特性:
- 初始可见性检查:首先检查元素是否已在视窗内
- 避免不必要的Observer:如果元素已可见,直接触发,不创建Observer
- 自动清理:触发后自动停止观察,节省资源
防重复触发
所有hooks都内置防重复触发机制:
- ✅ 状态管理确保回调只执行一次
- ✅ 提供reset方法手动重置状态
- ✅ 组件卸载时自动清理
错误处理
- ✅ 全局对象检测失败不会影响主流程
- ✅ 最大重试次数限制(5次)
- ✅ 合理的检测间隔(300ms)
🔧 高级用法
自定义全局对象检测
const CustomObjectTracker = () => {
const { reset } = useGlobalObjectChecker({
globalKey: "MyCustomSDK",
onReady: () => {
// 自定义SDK加载完成
window.MyCustomSDK.initialize()
},
enabled: true
})
return <div>等待自定义SDK加载...</div>
}多重条件检测
const MultiConditionTracker = () => {
const [isSDKReady, setIsSDKReady] = useState(false)
const [isUserReady, setIsUserReady] = useState(false)
// 检测SDK
useCrossSellTracker(() => {
setIsSDKReady(true)
}, !isSDKReady)
// 检测用户登录状态
useEffect(() => {
if (window.userAuth?.isLoggedIn()) {
setIsUserReady(true)
}
}, [])
// 两个条件都满足时才开始跟踪
const { ref } = useSmartVisibleCrossSellTracker({
onViewed: () => {
window.crossSellTracker?.logViewed("multi-condition-uuid")
},
enabled: isSDKReady && isUserReady
})
return (
<div ref={ref}>
<p>SDK状态: {isSDKReady ? "就绪" : "等待中"}</p>
<p>用户状态: {isUserReady ? "已登录" : "未登录"}</p>
</div>
)
}🔗 与Core SDK的配合使用
建议的使用模式:
- 应用初始化时:使用core SDK初始化全局实例
- 组件中:使用React hooks进行可见性跟踪
- 手动事件:直接调用core SDK的快捷方法
// App.tsx - 应用入口
import { initGlobalCrossSellTracker } from "@packages/cross-sell-tracking"
const App = () => {
useEffect(() => {
initGlobalCrossSellTracker({
apiKey: "your-api-key",
environment: "production"
})
}, [])
return <Router>...</Router>
}
// Component.tsx - 具体组件
import { useSmartVisibleCrossSellTracker } from "@packages/polling-checker"
const MyComponent = () => {
const { ref } = useSmartVisibleCrossSellTracker({
onViewed: () => window.crossSellTracker?.logViewed("uuid")
})
const handleClick = () => {
window.crossSellTracker?.logClicked("uuid")
}
return <div ref={ref} onClick={handleClick}>内容</div>
}🏗️ 最佳实践
- 优先使用SmartVisible:大多数场景下使用
useSmartVisibleCrossSellTracker - 合理设置阈值:根据元素大小和业务需求设置threshold
- 启用条件控制:使用enabled参数控制何时开始跟踪
- 状态重置:必要时使用reset方法重置跟踪状态
- 错误边界:在关键组件外包裹错误边界组件
