import { useEffect, useRef, useState } from 'react'
interface DebouncedComponentProps {
value: any
delay?: number
fallback?: React.ReactNode
children: React.ReactNode
}
export function DebouncedComponent({
value,
delay = 500,
fallback =
Loading...
,
children,
}: DebouncedComponentProps) {
const [shouldRender, setShouldRender] = useState(false)
const timeoutRef = useRef(null)
const prevValueRef = useRef(value)
const isInitialMount = useRef(true)
useEffect(() => {
if (isInitialMount.current || prevValueRef.current !== value) {
setShouldRender(false)
prevValueRef.current = value
if (timeoutRef.current) {
clearTimeout(timeoutRef.current)
}
timeoutRef.current = setTimeout(() => {
setShouldRender(true)
isInitialMount.current = false
}, delay)
}
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current)
}
}
}, [value, delay])
return shouldRender ? children : fallback
}