timer.js
const hasNativePerformanceNow = typeof performance === 'object'
&& typeof performance.now === 'function';
const now = hasNativePerformanceNow
? () => performance.now()
: () => Date.now();
export function cancelTimeout(timeoutID) {
cancelAnimationFrame(timeoutID.id);
}
export function requestTimeout(callback, delay) {
const start = now();
function tick() {
if (now() - start >= delay) {
callback.call(null);
} else {
timeoutID.id = requestAnimationFrame(tick);
}
}
const timeoutID = {
id: requestAnimationFrame(tick),
};
return timeoutID;
}
index.jsx
const IS_SCROLLING_DEBOUNCE_INTERVAL = 2000;
class Home extends React.Component {
constructor(props) {
super(props);
this.onScrollVertical = this.onScrollVertical.bind(this);
this.resetIsScrolling = this.resetIsScrolling.bind(this);
}
onScrollVertical(event) {
if (this.resetIsScrollingTimeoutId) {
cancelTimeout(this.resetIsScrollingTimeoutId);
}
this.resetIsScrollingTimeoutId = requestTimeout(
this.resetIsScrolling,
IS_SCROLLING_DEBOUNCE_INTERVAL,
);
}
resetIsScrolling() {
this.resetIsScrollingTimeoutId = null;
console.log('handle debounce...');
}
render() {
return (
<div
style={{ height: '80px', overflow: 'auto' }}
onScroll={this.onScrollVertical}
>
{
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((item) => (
<div style={{ height: '50px' }} key={item}>{item}</div>
))
}
</div>
);
}
}
export default Home;