TNG-Hooks
TNG-Hooks copied to clipboard
Feature: `useDebounce(..)` and `useThrottle(..)`
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 I want to take it
Excellent, would love the contribution. Do you have a good idea of how to proceed with implementing it?
@getify https://github.com/getify/TNG-Hooks/pull/22