You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在useEffect中对scrollY.onChange触发的函数做Debounce/Throttle处理

基于Lodash给滚动监听添加防抖/节流的实现方案

滚动监听场景更推荐用节流(Throttle),可以固定间隔时间触发回调,避免滚动过程中完全不执行逻辑;如果需要滚动停止后才执行逻辑,可以用防抖(Debounce)。具体实现步骤如下:

  • 先安装Lodash,推荐按需引入对应方法减少打包体积
  • 用useCallback包裹防抖/节流处理后的update函数,保证函数引用稳定,不会因为组件重渲染失效
  • 调整useEffect的依赖项,同时正确注销滚动监听事件、清理未执行的防抖/节流队列
import { useState, useEffect, useCallback } from "react";
import { useViewportScroll } from "framer-motion";
// 按需引入lodash的节流方法,要换防抖就把throttle改成debounce即可
import throttle from "lodash/throttle";

const useScrollScreen = () => {
  const { scrollY } = useViewportScroll();
  const [hidden, setHidden] = useState(false);

  // 用useCallback包裹保证引用稳定,节流时间可自行调整,这里设为200ms
  const update = useCallback(
    throttle(() => {
      if (scrollY?.current < scrollY?.prev) {
        console.log("SHOW");
        setHidden(false);
      } else if (scrollY?.current > 100 && scrollY?.current > scrollY?.prev) {
        setHidden(true);
      }
    }, 200),
    [scrollY]
  );

  useEffect(() => {
    const unsubscribe = scrollY.onChange(update);
    // 组件卸载时注销监听同时清空未执行的节流队列
    return () => {
      unsubscribe();
      update.cancel();
    };
  }, [update]);

  return [hidden, setHidden];
};

export default useScrollScreen;

额外说明:原代码的自定义Hook命名不符合React规范,自定义Hook必须以use开头,所以将scrollScreen调整为useScrollScreen,避免React语法检查报错。延迟时间可以根据业务需要调整,滚动场景一般设置100~300ms即可平衡流畅度和性能收益。

内容的提问来源于stack exchange,提问作者Martin Seubert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 02:21:01