Возникли проблемы при получении данных о событии из прослушивателя событий в ReasonReact - PullRequest
0 голосов
/ 18 октября 2018

Я пытаюсь реализовать динамическое изменение размера столбца в таблице (как в Excel или Google Sheets).

В моей функции рендеринга я использую обратный вызов handle, когда пользователь нажимает кнопку мыши при изменении размераcontrol:

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

В обработчике я хочу добавить новый прослушиватель событий для mousemove, чтобы, когда пользователь «перетаскивает», мы могли нарисовать что-то, чтобы указать, где будет заканчиваться край нового столбца.

В обработчике mousemove я думал, что могу отправить действие редуктора, содержащее координату clientX мыши, чтобы обновить состояние компонента, чтобы функция рендеринга могла рисовать что-то во время перетаскивания.

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) для получения конкретного значения int clientX, я получаю эту ошибку:

  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)

Мое понимание системы типов здесь ограничено, и я не уверен, как получитьзначение мышиной координаты клиента X в переменную.

1 Ответ

0 голосов
/ 19 октября 2018

Хотя события, полученные от React и от обработчиков событий, подключенных непосредственно к DOM, могут выглядеть одинаково, на самом деле они разные.React не дает вам необработанное событие DOM, но SyntheticEvent , и поэтому в Reason им были даны разные типы, о чем и сообщает ошибка типа.Вы не можете использовать Dom.event там, где ожидается ReactEvent.Mouse.t.В этом случае evt - это Dom.event, потому что он был получен путем подключения обработчика событий непосредственно к DOM с использованием bs-webapi, а ReactEvent.Mouse.clientX, конечно, ожидает ReactEvent.Mouse.t.

Так что вместо этогоиспользования ReactEvent.Mouse.clientX, вы должны использовать Webapi.Dom.MouseEvent.clientX.

К сожалению, это все равно не будет работать, потому что Webapi.Dom.MouseEvent.clientX ожидает Dom.mouseEvent, а не Dom.event, который является супертипом всех типов событий DOM и слишком общим для использования с функциями, специфичными для мыши.События.И это в свою очередь потому, что Webapi.Dom.EventTarget.addEventLsitener не может понять, что "mousemove" означает, что это событие мыши.Вместо этого вы должны использовать Webapi.Dom.EventTarget.addMouseMoveEventListener, что дает вам Dom.mouseEvent.

Обратите внимание, что ошибка типа, которую вы получаете, более запутанна, чем должна быть, потому что она выведет тип и укажет на ошибкунаходясь где-то, кроме того, где вы чувствуете, что ошибка возникла.Рекомендуется аннотировать типы, по крайней мере, когда вы получаете ошибку типа, которую вам трудно понять.Таким образом, компилятор не выведет тип как нечто, чего вы не ожидаете, и будет содержать источник ошибки.

Возможно, вы также захотите использовать Webapi.Dom.Document вместо Webapi.Dom.EventTarget.Document наследует все в EventTarget, но одновременно документирует и ограничивает тип, с которым вы работаете.

...