reactjs - 在 ReasonReact 中从事件监听器获取事件数据时遇到问题

标签 reactjs reason bucklescript reason-react bs-webapi

我正在尝试在表格(例如 Excel 或 Google 表格中)上实现动态列大小调整。

在我的渲染函数中,当用户在调整大小控件上单击鼠标时,我使用 handle 回调:

 <div
     className="resizer"
     onMouseDown={self.handle(handleColumnResizeStart)}
 />

在处理程序中,我想为 mousemove 添加一个新的事件监听器,以便当用户“拖动”时我们可以绘制一些内容来指示新列边缘的结束位置。

在 mousemove 处理程序中,我想我可以发送一个包含鼠标 clientX 坐标的 reducer 操作来更新组件状态,以便渲染函数可以在拖动时绘制一些东西。

let handleColumnResizeStart = (evt, self) => {
  /* this handler gets invoked when the mouse is moved */
  let handleMouseMove = evt => {

    Js.log(evt); /* in js land I can see that clientX is in that evt object */
    Js.log(ReactEvent.Mouse.clientX(evt)); /* but this creates type errors */


  };
  /* adds an event handler using the bs-webapi module */
  Webapi.Dom.EventTarget.addEventListener(
    "mousemove",
    handleMouseMove,
    document,
  );

};

当我尝试使用 ReactEvent.Mouse.clientX(evt) 获取 clientX 的特定 int 值时,出现以下错误:

  25 Webapi.Dom.EventTarget.removeEventListener(
  26 ┆   "mousemove",
  27 ┆   handleMouseMove,
  28 ┆   document,
  29 ┆ );

  This has type:
    ReactEvent.Mouse.t => unit
  But somewhere wanted:
    Dom.event => unit

  The incompatible parts:
    ReactEvent.Mouse.t (defined as
      ReactEvent.synthetic(ReactEvent.Mouse.tag))
    vs
    Dom.event (defined as Dom.event_like(Dom._baseClass))

>>>> Finish compiling(exit: 1)

我对类型系统的理解有限,我不确定如何将鼠标 clientX 坐标的值获取到变量中。

最佳答案

尽管从 React 接收的事件和从直接附加到 DOM 的事件处理程序接收的事件可能看起来相似,但实际上它们是不同的。 React 不会给你一个原始的 DOM 事件,而是一个 SyntheticEvent ,因此在 Reason 中它们被赋予了不同的类型,这就是类型错误通知您的内容。您不能在需要 ReactEvent.Mouse.t 的地方使用 Dom.event。在本例中,evt 是一个 Dom.event,因为它是通过使用 bs-webapi 将事件处理程序直接附加到 DOM 来获取的,并且ReactEvent.Mouse.clientX 当然需要 ReactEvent.Mouse.t

因此,您应该使用 Webapi.Dom.MouseEvent.clientX,而不是使用 ReactEvent.Mouse.clientX

不幸的是,这仍然不起作用,因为 Webapi.Dom.MouseEvent.clientX 需要 Dom.mouseEvent,而不是 Dom.event >,它是所有 DOM 事件类型的父类(super class)型,并且过于通用,无法与特定于鼠标事件的函数一起使用。这又是因为 Webapi.Dom.EventTarget.addEventLsitener 无法理解 "mousemove" 意味着它是一个鼠标事件。您应该使用 Webapi.Dom.EventTarget.addMouseMoveEventListener,它会为您提供 Dom.mouseEvent

请注意,您得到的类型错误比它需要的更令人困惑,因为它会推断类型并指向错误所在的位置,而不是您认为错误起源的位置。对类型进行注释是个好主意,至少当您遇到难以理解的类型错误时是这样。这样编译器就不会推断出您不希望的类型,并且会包含错误的根源。

您可能还想使用 Webapi.Dom.Document 而不是 Webapi.Dom.EventTargetDocument 继承了 EventTarget 中的所有内容,但会记录并限制您操作的类型。

关于reactjs - 在 ReasonReact 中从事件监听器获取事件数据时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52882248/

相关文章:

css - 带有原因 react 的 webpack css 加载器

types - ReasonML 类型与相同类型不匹配

module - 我可以用 1 个模块实现多种模块类型吗?

reason - 使用 bs-json 在 root 中使用动态键解码对象

reactjs - Jest.js 强制窗口未定义

javascript - React 组件没有函数或类?

reason - 如何在 ReScript 中为任意记录类型实现哈希函数?

Reason-react 渲染来自 json 的项目列表

CSS 无法在表单输入上设置宽度和其他属性

javascript - ReactJS:如何更改 URL 的链接预览?