Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2023-07-17 17:52:18 +02:00
parent 5f27996ed0
commit 5b590cdd47
No known key found for this signature in database
GPG key ID: B97799103358209B

View file

@ -7,32 +7,39 @@
import { useCallback, useEffect, useRef, useState } from 'react' import { useCallback, useEffect, useRef, useState } from 'react'
import { useInterval } from 'react-use' import { useInterval } from 'react-use'
const minimumTimeBetweenUpdateInterval = 200
const forceUpdateAfterTime = 1000
/** /**
* Takes a value that changes often and outputs the last value that hasn't been changed in the last interval. * Takes a value that changes often and outputs the last value that hasn't been changed in the last interval.
* *
* @param value The value to defer * @param value The value to defer
* @param initialValue The initial value that is used until the first update * @param initialValue The initial value that is used until the first update
* @param checkInterval The interval in ms that is used to check for updates. Default is 200ms.
* @return The slowed down value * @return The slowed down value
*/ */
export const useDeferredState = <T>(value: T, initialValue: T, checkInterval = 200): T => { export const useDeferredState = <T>(value: T, initialValue: T): T => {
const valueRef = useRef<T>(initialValue) const valueRef = useRef<T>(initialValue)
const lastTimestamp = useRef<number>(0) const lastIncomingUpdateTimestamp = useRef<number>(0)
const lastOutgoingUpdateTimestamp = useRef<number>(0)
const [deferredValue, setDeferredValue] = useState<T>(initialValue) const [deferredValue, setDeferredValue] = useState<T>(initialValue)
useEffect(() => { useEffect(() => {
valueRef.current = value valueRef.current = value
lastTimestamp.current = new Date().getTime() lastIncomingUpdateTimestamp.current = new Date().getTime()
}, [value]) }, [value])
useInterval( useInterval(
useCallback(() => { useCallback(() => {
const currentTimeStamp = new Date().getTime() const currentTimeStamp = new Date().getTime()
if (currentTimeStamp - lastTimestamp.current >= checkInterval) { if (
currentTimeStamp - lastIncomingUpdateTimestamp.current >= minimumTimeBetweenUpdateInterval ||
currentTimeStamp - lastOutgoingUpdateTimestamp.current >= forceUpdateAfterTime
) {
lastOutgoingUpdateTimestamp.current = currentTimeStamp
setDeferredValue(valueRef.current) setDeferredValue(valueRef.current)
} }
}, [checkInterval]), }, []),
checkInterval 100
) )
return deferredValue return deferredValue