【问题标题】:How to handle global DOM events in ReasonML/ReasonReact?如何在 ReasonML/ReasonReact 中处理全局 DOM 事件?
【发布时间】:2018-06-27 22:51:17
【问题描述】:

在 ReasonML 中侦听/处理全局 DOM 事件最惯用的方式是什么。

我正在构建 2048 游戏的 ReasonReact 版本,我需要在其中监听键盘事件。

在标准的 JS/React 应用程序中,我将有一个带有 componentDidMount 生命周期方法的组件,我将使用 document.addEventListener("keypress", [my_event_handler]) 收听事件,并在 componentWillUnmount 上使用 document.removeEventListener("keypress", [my_event_handler]) 不收听相同的事件。

在 Reason/ReasonReact 中访问 document.(addEventListener/removeEventListener) 最惯用的方法是什么?

【问题讨论】:

    标签: reason reason-react


    【解决方案1】:

    你可以在 ReasonReact 中做几乎相同的事情——它支持 didMountwillUnmount 生命周期方法,它们对应于它们的 ReactJS 同名:https://reasonml.github.io/reason-react/docs/en/lifecycles.html

    要添加和删除事件监听器,可以使用@glennsl 优秀的bs-webapi 包: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>,
    };
    

    【讨论】:

    • 如何访问活动的属性?作为 Reasonml 的新手,阅读 this,我希望访问 event.key,但我不能。我该如何理解该文件?
    • @GormCasper 您可以将key 用作函数,例如let handleKey = evt =&gt; Js.log2("Key pressed:", Dom.KeyboardEvent.key(evt));
    【解决方案2】:

    我最终编写了自己的绑定到addEventListenerremoveEventListener

    [@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";
    

    【讨论】:

    • 啊,我明白了,因为这两个函数在浏览器全局命名空间中可用。
    • 这个,监听 keydown 结合 ReactEventRe.Keyboard.key(event) 得到,比如说,被按下的键
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    相关资源
    最近更新 更多