Skip to content

Instantly share code, notes, and snippets.

@codersantosh
Last active January 13, 2023 15:52
Show Gist options
  • Select an option

  • Save codersantosh/fcfaee2e39fb560cb253cce704ef0133 to your computer and use it in GitHub Desktop.

Select an option

Save codersantosh/fcfaee2e39fb560cb253cce704ef0133 to your computer and use it in GitHub Desktop.
The AbcUseDelayFunction is a custom hook that allows you to delay the execution of a given function. It takes two arguments, the first argument is the function that you want to delay, and the second argument is the delay time in milliseconds (defaults to 2000ms).
If a function is called 100 times at once, the function is called 100 times but in the gap of time provided.
The AbcUseDelayFunction is a custom hook that allows you to delay the execution of a given function. It takes two arguments, the first argument is the function that you want to delay, and the second argument is the delay time in milliseconds (defaults to 2000ms).
The hook returns an object that contains two functions, delayFn and clearTimeout. You can use the delayFn function to call the delayed function and pass in any arguments that you want to pass to the delayed function. And you can use the clearTimeout function to clear the delay timer and stop the delayed function from being executed.
The hook uses the useState and useEffect hooks from the @wordpress/element package to manage the state and behavior of the delay timer. It also uses the useRef hook to store the timeout ID and the cloneDeep function from the lodash library to create a new array of args so that the state is not modified directly.
The hook uses the setTimeout function to delay the execution of the function, and it keeps track of the number of calls to the function and the arguments passed to the function. The hook also makes sure that the delayed function is only executed once all the calls have been made, and it clears the timeout when all the calls have been made.
It's important to thoroughly test the hook with different use cases before using it in a production environment. Also, make sure you're handling the case where the window object is not available.
/*WordPress*/
import {
useEffect,
useRef,
useState
} from "@wordpress/element";
/*Library*/
import {
cloneDeep
} from "lodash";
const AbcUseDelayFunction = (fn, delay = 2000) => {
if (!fn) return;
const [count, setCount] = useState(0);
const [totalFn, setTotalFn] = useState(0);
const [args, setArgs] = useState([]);
const timeoutIdRef = useRef();
const localCount = useRef( count );
const localArgs = useRef( args );
const localTotalFn = useRef( totalFn );
const setLocalCount = () => {
localCount.current++;
setCount(localCount.current)
};
const setLocalArgs = (arg) => {
localArgs.current.push(arg);
setArgs(localArgs.current)
};
const setLocalTotalFn = (type) => {
if( 'add' === type ){
localTotalFn.current++;
}
else{
localTotalFn.current--;
}
setTotalFn(localTotalFn.current)
};
useEffect(() => {
if (totalFn) {
timeoutIdRef.current = setTimeout(() => {
fn(...args[count]);
setLocalCount();
setLocalTotalFn();
}, delay);
}
else{
clearTimeout()
}
return () => {
clearTimeout()
};
}, [totalFn]);
const clearTimeout = () => {
window.clearTimeout(timeoutIdRef.current);
}
const delayFn = (...arg) => {
setLocalTotalFn('add');
setLocalArgs(arg);
};
return { delayFn, clearTimeout }
}
export default AbcUseDelayFunction;
/*WordPress*/
import {
useCallback
} from "@wordpress/element";
/*Hook*/
import AbcUseDelayFunction from "./use-delay-function";
/*Custom function*/
function myFunction(index) {
console.log(index,);
}
/*Component*/
export default function MyComponent() {
const useDelayedFn = useCallback(AbcUseDelayFunction, []);
const { delayFn } = useDelayedFn(myFunction);
return (
<div>
<button onClick={()=>delayFn()}>Delay</button>
{[0,1,2].map((value, index)=><button onClick={()=>delayFn(index)}>Delay</button>)}
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment