如何在React中正确使用lodash的throttle节流函数处理onScroll事件
React中使用lodash throttle触发次数异常的解决方案
问题原因
你遇到的触发两次的问题主要来自两个常见的使用错误:
- 未固定throttle实例:如果你直接在组件渲染逻辑、
onScroll属性中直接创建_.throttle实例,组件每次重渲染都会生成全新的节流函数,之前的节流时间记录会完全失效,无法达到预期的节流效果。 - lodash throttle默认配置问题:lodash的
throttle方法默认开启*leading: true*和*trailing: true*两个配置项:leading: true表示节流周期开始时立即触发一次函数trailing: true表示如果节流周期内有事件触发,周期结束后会额外触发一次函数
你看到的滚动3秒后生成的输出,就是trailing配置触发的收尾调用。
修复方案
- 用
useRef固定节流函数实例,保证组件整个生命周期内只生成一个throttle实例,不要每次渲染重复创建。 - 根据业务需要调整
trailing配置,如果不需要周期结束后的收尾调用,手动设置为false即可。 - 组件卸载时要主动取消节流函数并解绑事件,避免内存泄漏。
参考实现代码:
import { useRef, useEffect } from 'react'; import _ from 'lodash'; const List = () => { // 存储唯一的节流函数实例 const throttledHandleScroll = useRef( _.throttle(() => { console.log('滚动事件触发'); }, 3000, { // 不需要收尾触发则关闭该配置 trailing: false }) ).current; useEffect(() => { window.addEventListener('scroll', throttledHandleScroll); return () => { window.removeEventListener('scroll', throttledHandleScroll); // 卸载时取消未执行的节流调用 throttledHandleScroll.cancel(); }; }, [throttledHandleScroll]); // 其余组件逻辑 return <div className="long-list">/* 列表内容 */</div>; }
内容的提问来源于stack exchange,提问作者Sean Liu
相关产品推荐
相关产品推荐

