【问题标题】:Is there a way to create a global click handler that is guaranteed to run after other click handlers in TypeScript?有没有办法创建一个全局点击处理程序,保证在 TypeScript 中的其他点击处理程序之后运行?
【发布时间】:2022-01-04 19:28:16
【问题描述】:

我有一个用 TypeScript 编写的基于 ReactJS 的应用程序,我们为此实现了某些点击处理程序。

其他团队为此和应用程序做出贡献,甚至可以实现自己的处理程序和事件。问题是我们需要确保一个特定的点击处理程序需要保证在应用程序中的其他点击处理程序之后运行。

这需要是全局(React 外部)点击处理程序。

我知道我可以在 React 中管理全局 DOM 事件,即使使用钩子,但我还没有找到一种方法来遵循和尊重点击事件或任何类型事件的定义层次结构。

我还查看了这个 Stack Overflow 问题 global events,但无法确保我的点击处理程序优先于同一级别的其他人或保证我的点击处理程序先于其他人出现在 DOM 中。

如果您能指出正确的方向,我将不胜感激。

【问题讨论】:

  • “保证在其他点击处理程序之后运行”是什么意思?您是否需要等到所有非全局处理程序都完成工作,然后才在它们之后调用“全局”处理程序?异步处理程序呢?
  • 感谢@AndreyProgr,这正是我的意思是我的点击处理程序应该在所有其他点击处理程序之后最后执行。至于异步处理程序,我没有看到任何方法可以确保其他处理程序在我之前完成。
  • 一种方法是创建自己的事件调度队列机制并将所有处理程序注册到它,而不是直接注册本地 DOM 节点。通过使用这种代理,您可以控制和保证调度顺序。

标签: javascript reactjs typescript dom-events


【解决方案1】:

你可以用你自己的函数包装默认的点击处理程序。最简单的方法是将此代码放入您的自定义可点击组件中。例如:

  const Button = ({ onClick, ...props }) => {
    const handleClick = (...args) => {
      // you should add try ... catch and/or await here if needed
      onClick && onClick(...args);
      // this is your custom "global" handler imported from somewhere
      handleGlobalButtonClick();
    }
    return <button onClick={handleClick} {...props}> click me! </button>;
  }

这是我建议您使用的解决方案。尝试通过操作全局对象将此类函数“全局”注入所有可点击组件将使您的代码库高度耦合并显着降低可维护性。

您也可以通过创建HOC 来做同样的事情。在这种情况下,您将获得更大的灵活性。但是选择哪种方式高度取决于您项目的架构。

【讨论】:

  • 没有什么可以阻止其他代码执行此操作,可能在您包装它之后。所以不能保证这会让你“持久”
  • 是的,您可以添加数百个包装器,但这里定义的第一个将是调用堆栈中的最后一个?那么,这段代码有什么问题呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-08
  • 2016-04-20
  • 2011-02-24
  • 1970-01-01
  • 1970-01-01
  • 2014-03-12
  • 2013-06-09
相关资源
最近更新 更多