首页 > 解决方案 > 如何在 React 中使用 useLongPress.js 从 {...bind} 将参数传递给 onCancel?

问题描述

我在 React 中有一些这样的代码。我想拦截单击点击,以及长按长按,所以我使用了 useLongPress.js

所以,我想onClick={() => start(preset)}从按钮中删除并start(preset)shortPress函数中调用。但是我怎样才能通过preset论点呢?

const Presets = ({presetsList: presets, presetStart: start}) => {
    
    const longPress = () => {
          console.log('long click or long press');
          // Some other code... 
    }

    const shortPress = event => {
        console.log('single click or tap')
       // start(preset)
    }
    
    const bind = useLongPress(longPress, {onCancel: shortPress} )
      
    return (
        <section onContextMenu={(e)=> e.preventDefault()}>
            {presets.map( preset => {
                return <button 
                            key={presets.indexOf(preset)} 
                            onClick={() => start(preset)} 
                            {...bind} 
                            type="button" 
                        >
                            <span>{preset.time}</span>
                        </button>
            })}
        </section>
    )
}
 
export default Presets;

基本上,我需要onCancel{...bind}. 有没有办法做到这一点?

标签: javascriptreactjs

解决方案


TL;博士

{presets.map(preset => {
  const bind = useLongPress(longPress, { onCancel: shortPress.bind(null, preset) })
  return (
    <button 
      key={presets.indexOf(preset)} 
      onClick={() => start(preset)} 
      type="button" 
      {...bind}
    >
      <span>{preset.time}</span>
    </button>
})}

请阅读:

如果你看一下那个钩子库的代码,钩子会返回一堆事件处理程序供你传播到你的元素上。它依赖这些事件处理程序来知道长按何时发生或停止等。

对于其中一些事件侦听器和处理程序,将调用一个回调来执行一些逻辑并有条件地运行您提供的函数,就像onCancel您执行自己的逻辑一样。

不幸的是,您提到的包没有返回实际的cancel函数供您使用,但它返回的是一个对象,该对象具有该cancel函数作为其某些属性的值。

该对象包含我们之前讨论过的事件处理程序(您在元素上传播的那些),它看起来像这样:

{
  onMouseDown: start as MouseEventHandler<Target>,
  onMouseMove: handleMove as MouseEventHandler<Target>,
  onMouseUp: cancel as MouseEventHandler<Target>,
  onMouseLeave: cancel as MouseEventHandler<Target>,
  onTouchStart: start as TouchEventHandler<Target>,
  onTouchMove: handleMove as TouchEventHandler<Target>,
  onTouchEnd: cancel as TouchEventHandler<Target>,
}

但问题是这个cancel函数是useLongPress.js执行其逻辑并调用您的 onCancel 方法的事实。这也是使用useCallback. 所以真正可以将参数绑定到函数的唯一地方是调用useLongPress钩子时。

总之,作为一种肮脏的解决方法,您可以尝试像这样编写代码,但这不一定是性能最高或外观最漂亮的代码。所以我给你的建议是改变你的图书馆。(实际上很简单,甚至可以创建自己的钩子?)

{presets.map(preset => {
  const bind = useLongPress(longPress, { onCancel: shortPress.bind(null, preset) })
  return (
    <button 
      key={presets.indexOf(preset)} 
      onClick={() => start(preset)} 
      type="button" 
      {...bind}
    >
      <span>{preset.time}</span>
    </button>
})}

推荐阅读