前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在React中优雅的处理doubleClick

如何在React中优雅的处理doubleClick

作者头像
皮小蛋
发布2020-03-02 10:23:30
7.7K2
发布2020-03-02 10:23:30
举报
文章被收录于专栏:前端皮小蛋前端皮小蛋

背景

上午楼主遇到一个需要处理双击事件的需求,在这里介绍下如何在触发doubleCLick时间的时候, 不触发click事件的解决办法, 顺便分享给大家。

问题阐述

首先, 我们的DOM 是天然支持dbClick 事件的, 线上demo:

https://codepen.io/scaukk/pen/BaBoYeO

可以清晰的看到, 双击之后, 触发处理双击事件的逻辑, 但是同时也触发了两次click事件:

这个副作用不是我们预期的, 需要处理一下。

解决办法

解决办法也很简单: 延迟 click事件的处理, 直到判断这个click 不在 doubleClick 中。

原理

这个延迟的click事件会放在一个 Promise 队列中, 并处于pending状态。

当doubleClick事件触发之后, 就取消所有的Pending Promises, 这些事件也就不会执行。

可取消的Promise

要处理这些处于 penging 状态的Promise, 我们需要用到可取消的Promise, 这个话题我在另一篇文章中讨论过, 有兴趣的可以看一下:

https://segmentfault.com/a/1190000019456742

下面是一个可以cancel的Promise的简单实现:

代码语言:javascript
复制
export const cancellablePromise = promise => {
  let isCanceled = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then(
      value => (isCanceled ? reject({ isCanceled, value }) : resolve(value)),
      error => reject({ isCanceled, error }),
    );
  });

  return {
    promise: wrappedPromise,
    cancel: () => (isCanceled = true),
  };
};

要解决开头提到的这个问题, 我们就需要用到这个大杀器。

先看下最终的结果,双击一下:

主要代码:

代码语言:javascript
复制
const EnhancedClickableBox = stopTriggerClicksOnDoubleClick(ClickableBox)

const DoubleClickExample = () => (
  <EnhancedClickableBox
    onClick={() => console.log("on click")}
    onDoubleClick={() => console.log("on double click")}
  />
);

const App = () => {
  return (
    <DoubleClickExample />
  )
}

ReactDOM.render(<App />, document.getElementById("app"));

线上Demo:

https://codepen.io/scaukk/pen/yLBYojv

Hooks 版本

代码语言:javascript
复制
const ClickableBox = ({ onClick, onDoubleClick }) => {
  const [handleClick, handleDoubleClick] = useClickPreventionOnDoubleClick(onClick, onDoubleClick);

  return (
    <button onClick={handleClick} onDoubleClick={handleDoubleClick}>
      Click or double click
    </button>
  );
};

const DoubleClickExample = () => (
  <ClickableBox
    onClick={() => console.log("on click")} 
    onDoubleClick={() => console.log("on double click")}/>
);

const App = () => {
  return (
   <DoubleClickExample />
  )
}

ReactDOM.render(<App />, document.getElementById("app"));

https://codepen.io/scaukk/pen/OJLyrOM

是不是很简单~

结语

处理双击事件的时候, 最好还是处理掉不必要的click调用, 免得产生bug.

文中若有错误,欢迎指出, 欢迎留言交流。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端皮小蛋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 问题阐述
  • 解决办法
  • 原理
  • 可取消的Promise
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档