@mskcc/carbon-react
Version:
Carbon react components for the MSKCC DSM
45 lines (40 loc) • 1.44 kB
JavaScript
/**
* MSKCC 2021, 2024
*/
import { useState, useRef, useCallback, useEffect } from 'react';
/**
* `useDelayedState` mirrors `useState` but also allows you to add a delay to
* when your state updates. You can provide a second argument to `setState`,
* `delayMs`, which will be the time in milliseconds after which the state is
* updated.
*
* This hook will clean up pending timers in `useEffect` and will cancel any
* pending timers when a `setState` is called before the state is updated from
* a previous call
*/
function useDelayedState(initialState) {
const [state, setState] = useState(initialState);
const timeoutId = useRef(null);
// We use `useCallback` to match the signature of React's `useState` which will
// always return the same reference for the `setState` updater
const setStateWithDelay = useCallback(function (stateToSet) {
let delayMs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
window.clearTimeout(timeoutId.current ?? undefined);
timeoutId.current = null;
if (delayMs === 0) {
setState(stateToSet);
return;
}
timeoutId.current = window.setTimeout(() => {
setState(stateToSet);
timeoutId.current = null;
}, delayMs);
}, []);
useEffect(() => {
return () => {
window.clearTimeout(timeoutId.current ?? undefined);
};
}, []);
return [state, setStateWithDelay];
}
export { useDelayedState };