What's the most idiomatic way of listening/handling global DOM events in ReasonML.
I'm building a ReasonReact version of the 2048 game where I need to listen for keyboard events.
In a standard JS/React app I'd have a component with a componentDidMount
lifecycle method where I would listen to the event with document.addEventListener("keypress", [my_event_handler])
and unlisten to the same on componentWillUnmount
with document.removeEventListener("keypress", [my_event_handler])
.
What's the most idiomatic way of accessing document.(addEventListener/removeEventListener) in Reason/ReasonReact?
You can do pretty much the same thing in ReasonReact–it supports the didMount
and willUnmount
lifecycle methods, which correspond to their ReactJS namesakes: https://reasonml.github.io/reason-react/docs/en/lifecycles.html
To add and remove event listeners, you can use @glennsl's excellent bs-webapi package: https://redex.github.io/package/bs-webapi
Here are some examples of adding and removing event listeners: https://github.com/reasonml-community/bs-webapi-incubator/blob/24cee2500b9c98355a14896fa9fc4ceb8a3e2258/tests/dom/events/eventTarget_test.re
Putting it all together, you could have a component like this:
/* 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>,
};
I ended up writing my own bindings to addEventListener
and 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";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With