@theoplayer/react-native-ui
Version:
A React Native UI for @theoplayer/react-native
37 lines (36 loc) • 1.46 kB
JavaScript
import { useCallback, useEffect, useRef, useState } from 'react';
/**
* A throttled version of React's `useState` that limits how often the state is updated.
*
* When `setValue` is called repeatedly, the state will update immediately if enough time
* has passed since the last update. Otherwise, it schedules an update after the remaining
* throttle interval. The most recent value is always applied eventually (trailing flush).
*
* @param initialValue The initial state value.
* @param intervalMs The minimum interval (in milliseconds) between state updates.
* @returns A tuple of `[state, setValue]`, just like `useState`.
*/
export function useThrottledState(initialValue, intervalMs) {
const [state, setState] = useState(initialValue);
const lastExecuted = useRef(0);
const timeoutRef = useRef();
const setThrottled = useCallback((value, forced = false) => {
const now = Date.now();
const timeSinceLast = now - lastExecuted.current;
clearTimeout(timeoutRef.current);
if (forced || timeSinceLast >= intervalMs) {
setState(value);
lastExecuted.current = now;
} else {
timeoutRef.current = setTimeout(() => {
setState(value);
lastExecuted.current = Date.now();
}, intervalMs - timeSinceLast);
}
}, [intervalMs]);
useEffect(() => {
return () => clearTimeout(timeoutRef.current);
}, []);
return [state, setThrottled];
}
//# sourceMappingURL=useThrottledState.js.map