here is my weirdDebounce function:
// prevents our function from being repeatedly called
function weirdDebounce(f, wait) {
let timeout = null;
return function() {
let ctx = this,
args = arguments,
callIt = !timeout;
clearTimeout(timeout);
// prevent the function from being called again until
// the timeout has finished
timeout = setTimeout(function() {
timeout = null;
}, wait);
// call the function immediately
if (callIt) f.apply(ctx, args);
};
}
I use it like this and it's called inside App.jsx:
function App ({ store }) {
const history = useHistory();
let someClassVariable = useMemo(() => new SomeClass(store, history),[store, history]);
window.testFunction = weirdDebounce(function(param1, param2, param3 = false) {
someClassVariable.someFunction(param1, param2, history, param3).then(function() {});
}, 2000);
return (// some jsx)
}
export default connect(mapStateToProps)(App)
It worked in Vue, but when I do it in React and run the same function twice, it ignores the timeout and still runs it. I tried wrapping the function in a useEffect, and I tried wrapping it in a useCallback. Wrapping it inside a useCallback made it listen to the timeout, but then things started to be sloppy, not work/be weird.
I actually have more React experience than Vue but I'm just not sure how to solve this, any hands?.
Also the params don't really matter, it's just the fact that in React it's ignoring the 2000ms timeout when running window.testFunction twice.
I would appreciate any help I can get with this, thank you.
Edit: using useConstant made it listen to the timeout, but there is a problem. the classVariable is changing depending on the store and it's going to change every-time this function is called, so that means that using useConstant won't be good because the function won't use the new state of the variable it will use the old one which makes certain things not work.
Update: I solved it by wrapping it with a useDebounce hook:
import { useCallback, useRef, useEffect } from "react";
// prevents our function from being repeatedly called
function weirdDebounce(f, wait) {
let timeout = null;
return function() {
let ctx = this,
args = arguments,
callIt = !timeout;
clearTimeout(timeout);
// prevent the function from being called again until
// the timeout has finished
timeout = setTimeout(function() {
timeout = null;
}, wait);
// call the function immediately
if (callIt) f.apply(ctx, args);
};
}
export const useDebounce = (cb, delay) => {
const cbRef = useRef(cb);
useEffect(() => {
cbRef.current = cb;
});
return useCallback(
weirdDebounce((...args) => cbRef.current(...args), delay),
[delay]
);
};