使用React Hooks节流Touch事件的问题求助
嘿,我完全懂你遇到的困扰——触摸拖动时数字跳得太频繁,想靠lodash的throttle节流却没生效对吧?我来帮你捋清楚问题出在哪,以及怎么解决。
首先,你之前的节流写法有个核心问题:你只是把传入的touchPosition原封不动返回,根本没把更新数字的逻辑放进节流函数里,而且可能也没在触摸事件回调里正确调用这个节流后的方法。咱们得把节流逻辑和数字更新绑定起来,再配合位移阈值,才能实现精准控制。
给你一个调整后的完整示例,核心做了这几件事:
- 用
useRef正确保存节流函数的实例(避免组件重渲染时重新创建) - 在节流回调里计算触摸的位移差,设置一个阈值(比如20px),只有拖动超过这个距离才增减数字
- 处理
touchstart记录初始位置,touchmove里调用节流函数,还加了e.preventDefault()防止页面滚动干扰
import { useRef, useState } from 'react'; import throttle from 'lodash.throttle'; function DraggableCounter() { const [count, setCount] = useState(0); const initialY = useRef(0); // 定义节流后的触摸处理函数,200ms内只执行一次 const throttledTouchHandler = useRef( throttle((currentY) => { const moveDistance = initialY.current - currentY; // 设定拖动阈值,超过20px才触发数字变化 if (moveDistance > 20) { setCount(prev => prev + 1); initialY.current = currentY; // 更新初始位置,避免连续触发 } else if (moveDistance < -20) { setCount(prev => prev - 1); initialY.current = currentY; } }, 200) ).current; const handleTouchStart = (e) => { // 记录触摸开始时的Y坐标 initialY.current = e.touches[0].clientY; }; const handleTouchMove = (e) => { e.preventDefault(); // 阻止默认滚动行为,避免干扰拖动 const currentY = e.touches[0].clientY; // 调用节流后的处理函数 throttledTouchHandler(currentY); }; return ( <div onTouchStart={handleTouchStart} onTouchMove={handleTouchMove} style={{ width: '250px', height: '250px', background: '#f0f0f0', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '32px', borderRadius: '8px', userSelect: 'none' }} > {count} </div> ); } export default DraggableCounter;
为什么这个写法能生效?
- 节流函数真正包裹了数字更新的逻辑,而不是单纯返回触摸位置
- 位移阈值的设置让你必须拖动到一定距离才会改变数字,解决了“难以精准定位特定数字”的问题
useRef保存节流函数实例,确保组件每次重渲染时用的都是同一个节流函数,不会失效
你可以试试这个写法,应该就能实现你想要的精准拖动增减效果了。
内容的提问来源于stack exchange,提问作者Davtho1983
相关产品推荐
相关产品推荐

