如何将useSwipeable事件处理器正确绑定到多个DOM元素
问题根因
这是react-swipeable的使用方式错误,和React本身逻辑无关:useSwipeable返回的handlers对象内部会维护单个DOM节点的ref引用,你把同一个handlers展开绑定到多个div上时,每绑定一个新元素,内部存的节点引用就会被新元素覆盖,到最后只会保留最后一个绑定的节点(也就是示例里的蓝色div),自然只有最后一个元素能触发事件。
你写的refPassthrough也有一样的问题:单个useRef只能存一个DOM节点,绑给多个元素的话,最后ref.current只会剩下最后一个元素的引用。
修复方法
别把同一个useSwipeable生成的handlers复用到多个元素上,每个滑块单独生成自己的事件处理器就行:
- 把单个滑块抽成独立组件
- 在滑块组件内部调用
useSwipeable,给每个滑块实例生成独立的handlers和ref,从根源上避免引用覆盖的问题
修复后的可运行代码
import { useRef } from "react"; import { useSwipeable } from "react-swipeable"; // 单个滑块组件,每个实例独立绑定触摸事件 function SwipeSlider({ bgColor }) { const handlers = useSwipeable({ onTouchEndOrOnMouseUp: (e) => console.log("滑块拖拽结束,提交值", e) }); const sliderRef = useRef(); const refPassthrough = (el) => { handlers.ref(el); sliderRef.current = el; }; return ( <div {...handlers} ref={refPassthrough} style={{ backgroundColor: bgColor, height: "50px" }} ></div> ) } export default function App() { // 模拟批量渲染20-30个滑块的场景 const sliderCount = 30; const sliderList = Array.from({length: sliderCount}, (_, i) => ({ id: i, bgColor: i % 3 === 0 ? "red" : i%3 ===1 ? "green" : "blue" })) return ( <div> <h1>滑块触摸事件测试</h1> {sliderList.map(item => ( <SwipeSlider key={item.id} bgColor={item.bgColor} /> ))} </div> ); }
不管渲染多少个滑块,每个滑块的触摸结束事件都会独立触发,不会再出现只有最后一个生效的问题。
内容的提问来源于stack exchange,提问作者Bill O
相关产品推荐
相关产品推荐

