TNG-Hooks icon indicating copy to clipboard operation
TNG-Hooks copied to clipboard

Feature: `useDebounce(..)` and `useThrottle(..)`

Open getify opened this issue 5 years ago • 3 comments

For posterity sake, let's clarify that throttling and debouncing are in fact distinct, while still clearly being related.

But both of these seem like worthwhile decorative hooks to add, which allow you to ensure that an Articulated Function is invoking another function only under certain time-based thresholds.

For example, it could be useful to wrap an effect with one of these hooks.

Here's how I envision them working:

function init() {
   var theBtn = useState(null);
   var throttled = useThrottle(tap,100);
   var debounced = useDebounce(hit,300);

   useEffect(function onInit(){
      theBtn = document.getElementById("the-button");
      theBtn.addEventListener("mousedown",throttled,false);
      theBtn.addEventListener("mouseup",debounced,false);
   },[]);
}

function tap() {
   console.log("tap!");
}

function hit() {
   console.log("hit!");
}

init = TNG(init);

In this code, as you clicked on the button really fast, you would see "tap!" printed in the console at most once per 100ms, but the "hit!" message wouldn't be printed until all it had been at least 300ms since the last "mouseup".

These two hooks also need to support an optional third parameter, a guards-list, similar to useEffect(..) and useMemo(..), which conditionally redefines the debounced/throttled function if the guards have changed (aka, if closure is required).


Implementation wise, I see useThrottle(..) and useDebounce(..) as convenience wrappers around useState(..), in that they create and store a throttled/debounced function in a state slot (so that work only happens the first time), and thereafter just keep returning a reference to that same function. That makes it "safe" even for inline/nested functions -- unlike the useMemo(..) hook (which reacts to different function references even if they're "the same function").

getify avatar Jan 13 '19 17:01 getify

@getify I want to take it

yossi-eynav avatar Jan 14 '19 09:01 yossi-eynav

Excellent, would love the contribution. Do you have a good idea of how to proceed with implementing it?

getify avatar Jan 14 '19 12:01 getify

@getify https://github.com/getify/TNG-Hooks/pull/22

yossi-eynav avatar Feb 22 '19 13:02 yossi-eynav