I’m trying to implement a debounce function using closure with typescript React.
The problem is that it seems it’s made a new reference of the function every time when I try to pass an event argument. So I think it has something to do with passing and executing _handleScroll
… Can anyone help me?
This doesn’t work
const _handleScroll = (e: UIEvent<HTMLElement>): (() => void) => {
e.stopPropagation();
let prev = Date.now();
const debounce = 500; // 500ms
let counter = 0;
return () => {
const now = Date.now();
if (prev - now > debounce) {
prev = now;
setScrollHeight(e.currentTarget.scrollTop);
}
++counter;
console.log("@@@", { now, prev, counter }); // result: counter: 1, 1, 1,...
};
};
...
<div
className="h-full overflow-y-auto"
onScroll={(e) => _handleScroll(e)()}
>
...
But this works
const _handleScroll = (): (() => void) => {
// e.stopPropagation();
let prev = Date.now();
const debounce = 500; // 500ms
let counter = 0;
return () => {
const now = Date.now();
if (prev - now > debounce) {
prev = now;
// setScrollHeight(e.currentTarget.scrollTop);
}
++counter;
console.log("@@@", { now, prev, counter }); // result: counter: 1, 2, 3,...
};
};
...
<div className="h-full overflow-y-auto" onScroll={_handleScroll()}>
...
2
Answers
In second block of code that you provided when you were passing handle scroll like onScroll={_handleScroll()} you are passing returned value of that function.
But in first block of code you’re passing onScroll={_handleScroll} you’re actually passing reference of that function. and every time your component rerenders the reference passed to the div will change
if you want to prevent that use useCallback hook it’s similar to useEffect you wrap your function in it and pass your dependencies in [] it baiscally caches your function reference and only changes it when your dependencies change
Hope this helps
I think it would be helpful if I understand what you want.
_handleScroll will be activated every scrolling but state updated 500ms.