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
相关产品推荐
相关产品推荐

