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

如何将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:12:25