Как обрабатывать глобальные события DOM в ReasonML / ReasonReact?

Какой самый идиоматический способ прослушивания / обработки глобальных событий DOM в ReasonML.

Я создаю версию ReasonReact игры 2048, в которой мне нужно отслеживать события клавиатуры.

В стандартном приложении JS / React у меня был бы компонент с componentDidMount методом жизненного цикла, в котором я бы прослушивал событие с document.addEventListener("keypress", [my_event_handler]) и не слушал бы его componentWillUnmount с document.removeEventListener("keypress", [my_event_handler]).

Какой самый идиоматический способ доступа к документу (addEventListener / removeEventListener) в Reason / ReasonReact?


person Alan R. Soares    schedule 27.06.2018    source источник


Ответы (2)


Практически то же самое можно делать в ReasonReact - он поддерживает методы жизненного цикла didMount и willUnmount, которые соответствуют их тезкам ReactJS: https://reasonml.github.io/reason-react/docs/en/lifecycles.html

Для добавления и удаления прослушивателей событий вы можете использовать отличный пакет bs-webapi от @ glennsl: https://redex.github.io/package/bs-webapi.

Вот несколько примеров добавления и удаления прослушивателей событий: https://github.com/reasonml-community/bs-webapi-incubator/blob/24cee2500b9c98355a14896fa9fc4ceb8a3e2258/tests/dom/events/eventTarget_test.re

Собрав все это вместе, у вас может получиться такой компонент:

/* src/components/MyComponent.re */
let document = Webapi.Dom.Document.asEventTarget(Webapi.Dom.document);
let handleKey = _ => Js.log("Key pressed");
let component = ReasonReact.statelessComponent("MyComponent");
let make = _children => {
  ...component,
  didMount: _self =>
    Webapi.Dom.EventTarget.addEventListener("keypress", handleKey, document),
  willUnmount: _self =>
    Webapi.Dom.EventTarget.removeEventListener("keypress", handleKey, document),
  render: _self => <p> (ReasonReact.string("Hello")) </p>,
};
person Yawar    schedule 28.06.2018
comment
Как получить доступ к объектам на мероприятии? Вы новичок в Reasonml и читаете это, я бы ожидал получить доступ к event.key, но не могу. Как мне понять этот файл? - person Gorm Casper; 26.07.2018
comment
@GormCasper вы можете использовать key как функцию, например. let handleKey = evt => Js.log2("Key pressed:", Dom.KeyboardEvent.key(evt)); - person Yawar; 26.07.2018

В итоге я написал собственные привязки к addEventListener и removeEventListener:

[@bs.val]
external add_keyboard_event_listener :
  (string, ReactEventRe.Keyboard.t => unit) => unit =
  "addEventListener";

[@bs.val]
external remove_keyboard_event_listener :
  (string, ReactEventRe.Keyboard.t => unit) => unit =
  "removeEventListener";
person Alan R. Soares    schedule 28.06.2018
comment
Ах, я вижу, это работает, потому что эти две функции доступны в глобальном пространстве имен браузера. - person Yawar; 29.06.2018
comment
Это, прислушиваясь к keydown в сочетании с ReactEventRe.Keyboard.key(event), чтобы получить, скажем, нажатую клавишу - person Gorm Casper; 26.07.2018