WTQ
284 文字
1 分
react-draggable使用随笔

react-draggable 避免触发组件 onClick 事件#

最近在工作过程中需要封装移动拖拽组件,于是使用三方库 React-draggable 进行封装。但是在使用过程中发现当使用<Draggable>包裹的组件存在 onClick 事件,则会在拖拽后触发 onClick 事件。代码如下:

<Draggable>
  <button onClick={() => console.log('被点击')}>按钮</button>
</Draggable>

于是用一个变量标记组件正在拖动。

import Draggable from 'react-draggable';

function App() {
  let dragging = false;
  const onStart = () => {
    console.log('drag start');
    // dragging = true;
  };
  const onDrag = () => {
    console.log('drag Drag');
    dragging = true;
  };

  const onStop = () => {
    console.log('drag stop');

    setTimeout(() => {
      dragging = false;
    }, 0);
  };

  const onClick = () => {
    if (dragging) return;
    console.log('被点击');
  };

  return (
    <div>
      <Draggable onStart={onStart} onDrag={onDrag} onStop={onStop}>
        <button onClick={onClick}>按钮</button>
      </Draggable>
    </div>
  );
}

这段代码的关键是 setTimeout(() => { dragging = false; }, 0)。这里有几个关键点:

  1. 在 react-draggable 源码中,onStartonDragonStop分别被绑定在 Mouse 事件的mousedownmousemovemouseup上,因此上述函数执行顺序是,onStart -> onDrag -> onStop -> onClick
  2. onClick是在onStop之后执行,因此需要通过setTimeoutdragging的赋值延迟到下一个onClick的宏任务后执行。
react-draggable使用随笔
https://www.aklelouch.cn/posts/2024-06/20240623-01/react-draggable使用随笔/
作者
@CJT  &  @WTQ
公開日
2024-06-23
ライセンス
CC BY-NC-SA 4.0