在 React 中覆盖 onClick

Overriding onClick in React

提问人:Andrew Townsend 提问时间:1/9/2023 更新时间:1/10/2023 访问量:565

问:

这是一个有点奇怪的问题。我正在 React 中使用事件类型,我们希望在某些情况下使用 onClick,在其他情况下使用 onPointerDownCapture(出于原因)。但为了更笼统地说,它可以是任何两个不同的类似点击的事件。问题在于,虽然我们可以在表达式的右侧分配任何函数处理程序,但左侧本质上必须是静态的。所以

<按钮与 vsonClick={handler}onPointerDownCapture={handler}onMouseDown={handler} />

我认为对于大多数用例来说,仅使用 onPointerDownCapture 就可以了,但在一个完美的世界里,我将能够在运行时根据其他变量在它们之间切换。是否可以覆盖按钮/div/任何原型或其他东西上的 onClick,使其成为我想要的任何事件类型?

很多谷歌搜索。没有成功。

JavaScript reactjs typescript 事件 dom-events

评论

0赞 merryweather 1/9/2023
“覆盖”是什么意思?您不需要覆盖。你可以只使用,如果更改,它会重新渲染按钮(有效地“删除”原始侦听器)。onClick={shouldBeUsingOnClick ? handler : undefined}shouldBeUsingOnClick

答:

1赞 hackape 1/9/2023 #1

我不完全理解你所说的“覆盖onClick”是什么意思,但是

问题在于,虽然我们可以在表达式的右侧分配任何函数处理程序,但左侧本质上必须是静态的。

这不是真的,左侧可能是动态的,方法如下:

<button {...({ [eventName]: handler })} />

我想这解决了你的问题。


好的,上面的语法有点简洁,而且不可否认地令人困惑。这是很好的旧 JSX 传播道具语法,只是在内联对象文字之上。

我会给你另一种等效的形式,希望它应该更具可读性。

const eventName = someCondition ? "onPointerDownCapture" : "onClick"

const props = { 
  [eventName]: handler
}

<button {...props} />

评论

0赞 Andrew Townsend 1/10/2023
也许我做得不对,但 TS 抛出一个错误,说属性“clickEvent”在类型“DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'.ts(2322) 中不存在属性”clickEvent“ 根据我用大括号和括号包装事物的方式,它经常告诉我”......”是意料之中的。
0赞 hackape 1/10/2023
你能用代码和 TS 错误的屏幕截图更新你的问题吗?
0赞 Andrew Townsend 1/10/2023
少一个屏幕截图,多一些相关代码:let clickEvent = <condition> ?onPointerDownCapture:onClick;<button type=“button” {(clickEvent=handlePayButton)} /> 在这次尝试中,我得到“......expected“错误。如果我在clickEvent声明字符串中设置函数名称,则会得到“类型'()=>void'不可分配给类型'string'”
0赞 hackape 1/10/2023
应该是 .你没有仔细阅读。<button type="button" {...({ [clickEvent]: handlePayButton })} />
0赞 Andrew Townsend 1/10/2023
我显然看不懂。这很狂野(而且有效)。为了我自己的启发,这里到底发生了什么?
0赞 AchiPapakon 1/9/2023 #2

您必须使用这些属性名称,并且对所有 3 个属性使用相同的函数名称。

这 3 个属性的作用是注册关联的事件。

也许你可以使用 一个 并在那里有条件地添加一个事件侦听器,而不是建议的 React 属性。useEffect

0赞 Matija Sirk 1/10/2023 #3

我认为最好的是评论@vera解决方案。将额外的 prop 传递给组件(例如 isOnClick),并基于它向事件处理程序 prop 传递回调或 undefined:

function Component(props: { isOnClick: boolean; callback: () => void }) {
  return (
    <div
      onClick={props.isOnClick ? props.callback : undefined}
      onMouseDown={props.isOnClick ? undefined : props.callback}
    />
  );
}

请注意,将 undefined 传递给 prop 与不设置该 prop 相同。

或者有条件地返回组件:

function Component(props: { isOnClick: boolean; callback: () => void }) {
  if (props.isOnClick) {
    return <div onClick={props.callback}/>
  } else {
    return <div onMouseDown={props.callback}/>
  };
}