2

我正在尝试在表格上实现动态列大小调整(例如在 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坐标的值转换为变量。

4

1 回答 1

3

尽管从 React 和直接附加到 DOM 的事件处理程序接收到的事件看起来很相似,但它们实际上是不同的。React 没有给你一个原始的 DOM 事件,而是一个SyntheticEvent,因此在 Reason 中它们被赋予了不同的类型,这就是类型错误通知你的内容。您不能在预期的Dom.event地方使用 a 。ReactEvent.Mouse.t在这种情况下evtDom.event,因为它是通过使用 直接将事件处理程序附加到 DOM 来获得的bs-webapiReactEvent.Mouse.clientX当然需要ReactEvent.Mouse.t.

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

不幸的是,这仍然行不通,因为Webapi.Dom.MouseEvent.clientX需要 a Dom.mouseEvent,而不是 a Dom.event,它是所有 DOM 事件类型的超类型,并且过于笼统,无法与特定于鼠标事件的函数一起使用。而这反过来又是因为Webapi.Dom.EventTarget.addEventLsitener无法理解这"mousemove"意味着它是一个鼠标事件。您应该改用Webapi.Dom.EventTarget.addMouseMoveEventListener,它确实给了您一个Dom.mouseEvent.

请注意,您得到的类型错误比它需要的更令人困惑,因为它会推断类型并指出错误在您认为错误起源之外的某个地方。注释类型是个好主意,至少当您遇到难以理解的类型错误时。这样编译器就不会将类型推断为您不期望的类型,并且将包含错误的来源。

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

于 2018-10-18T21:38:51.490 回答