utils/hooks/useCnzz/index.js
import { useRef, useMemo } from 'react'
import { useExternal } from 'ahooks'
/**
* cnzz统计hook
* @returns
*/
const useCnzz = () => {
const actionsRef = useRef({})
// 动态注入cnzz统计,useExternal可以保证资源全局唯一
const status = useExternal('https://v1.cnzz.com/z_stat.php?id=xxx', {
type: 'js',
js: {
async: true
}
})
const actions = useMemo(() => {
if (status === 'ready') {
Object.assign(actionsRef.current, {
push: (args) => {
window._czc?.push(args)
}
})
}
return actionsRef.current
}, [status]) // eslint-disable-line
return actions
}
export default useCnzz
demo/cnzz.js
import React from 'react'
import useCnzz from 'utils/hooks/useCnzz'
import { Button } from 'antd'
export default (props) => {
const { push } = useCnzz()
// 点击埋点
const handleClick = () => {
push(['_trackEvent', '顶部状态栏', '测试', '测试', 1, 'test'])
}
return (
<Button type="primary" onClick={handleClick}>
埋点
</Button>
)
}
使用了useMemo来避免在每次render时创建新的actions对象,而是在status发生变化时更新当前的actions对象,可以保证只在status变化时更新actions对象,避免了不必要的重新渲染。 此外,通过使用useRef来存储actions对象,可以避免在每次组件渲染时创建新的actions对象,也可以避免在每次状态变化时重新计算actions对象。