const [isFocused, setIsFocused] = useState(0)
const refCurrent = useObserver(1, setIsFocused)
const [countNumber, setCountNumber] = useState({
paymentNum: 0,
countriesNum: 0,
accrueNum: 0,
})
const { paymentNum, countriesNum, accrueNum } = countNumber
useEffect(() => {
if (isFocused > 0) {
const promises = [
countUp(872, 'paymentNum'),
countUp(140, 'countriesNum'),
countUp(877, 'accrueNum'),
]
Promise.all(promises).then()
}
}, [isFocused])
const countUp = async (end: number, name: string) => {
return new Promise<void>((resolve) => {
const stepTime = Math.abs(Math.floor(2000 / end))
let currentNum = 0
const counter = setInterval(() => {
currentNum += 1
setCountNumber((prev) => ({
...prev,
[name]: currentNum,
}))
if (currentNum === end) {
clearInterval(counter)
resolve()
}
}, stepTime)
})
}
return(
{paymentNum}
<span>만+</span>
)
import { useEffect, useRef } from 'react'
export const useObserver = (
navNumber: number,
setNavNumber: React.Dispatch<React.SetStateAction<number>>,
) => {
const options = {}
const refElement = useRef<HTMLDivElement>(null)
useEffect(() => {
const osv = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
setNavNumber(navNumber)
} else {
setNavNumber(0)
}
}, options)
if (refElement.current) {
osv.observe(refElement.current)
}
return () => osv.disconnect()
}, [])
return refElement
}