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

React页面滚动方向检测:如何更新prev滚动位置值

嘿,这个问题我之前做React项目时也踩过坑!你的核心问题很明确:把prev存在了componentDidMount的局部变量里——这个变量只会在组件挂载时赋值一次,后续触发滚动事件时,拿到的永远是初始的滚动位置,自然没法正确判断滚动方向。完全不用定时器这种非常规方案,咱们用React组件的实例属性或者状态就能轻松解决。

解决方案1:使用组件实例属性(推荐,无额外重渲染)

如果这个滚动位置不需要驱动视图更新,直接把上一次的滚动值存在组件实例上就好,这样既不会触发不必要的重渲染,又能持续更新值:

componentDidMount() {
  // 初始化实例属性为当前滚动位置
  this.prevScrollY = window.scrollY;
  window.addEventListener('scroll', this.handleNavigation);
}

handleNavigation = () => {
  const currentScrollY = window.scrollY;
  // 对比上一次和当前的滚动位置
  if (this.prevScrollY > currentScrollY) {
    console.log("scrolling up");
  } else if (this.prevScrollY < currentScrollY) {
    console.log("scrolling down");
  }
  // 每次滚动后更新实例属性,为下一次判断做准备
  this.prevScrollY = currentScrollY;
};

// 别忘了在组件卸载时移除监听,避免内存泄漏
componentWillUnmount() {
  window.removeEventListener('scroll', this.handleNavigation);
}

解决方案2:使用组件State(适合需要联动视图的场景)

如果后续需要根据滚动方向更新页面UI(比如显示/隐藏导航栏),可以把上一次的滚动值存在State里,这样值变化时会自动触发组件重渲染:

state = {
  prevScrollY: 0
};

componentDidMount() {
  this.setState({ prevScrollY: window.scrollY });
  window.addEventListener('scroll', this.handleNavigation);
}

handleNavigation = () => {
  const currentScrollY = window.scrollY;
  const { prevScrollY } = this.state;
  
  if (prevScrollY > currentScrollY) {
    console.log("scrolling up");
  } else if (prevScrollY < currentScrollY) {
    console.log("scrolling down");
  }
  
  // 更新State中的上一次滚动位置
  this.setState({ prevScrollY: currentScrollY });
};

componentWillUnmount() {
  window.removeEventListener('scroll', this.handleNavigation);
}

关键总结

核心思路就是把上一次的滚动位置存在组件能持续访问的地方(实例属性或State),每次滚动事件触发后更新这个值,这样下一次判断时就能拿到正确的对比值了。完全不需要定时器,这才是符合React组件生命周期的常规解决方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:27:13