官术网_书友最值得收藏!

Working with DOM

Let's try working with the DOM in pure Reason before jumping into ReasonReact. We'll write a module that does the following:

  • Creates a DOM element
  • Sets the innerText of that element
  • Appends that element to the body of the document

Create an index.html file in the project's root with the following content:

<html>
<head></head>
<body>
<!-- if "in-source": false -->
<script type="module" src="lib/es6/src/Demo.bs.js"></script>

<!-- if "in-source": true -->
<!-- <script type="module" src="src/Demo.bs.js"></script> -->
</body>
</html>

Notice the type="module" attribute on the script tag. If all module dependencies are ES Module (ESM) compliant, and they are all available from within the browser, you don't need a module bundler to get started (assuming you're using a browser that supports ES modules).

In Greeting.re, add the following greeting function:

let greeting = name => {j|hello $name|j};

And in Demo.re, add the following code:

[@bs.val] [@bs.scope "document"]
external createElement : string => Dom.element = "";

[@bs.set] external setInnerText : (Dom.element, string) => unit = "innerText";

[@bs.val] [@bs.scope "document.body"]
external appendChild : Dom.element => Dom.element = "";

let div = createElement("div");
setInnerText(div, Greeting.greeting("world"));
appendChild(div);

Using BuckleScript's powerful interoperability features (which we will dive into in Chapter 4, BuckleScript, Belt and Interoperability) the preceding code binds to existing browser APIs, namely document.createElement, innerTextand document.body.appendChild, and then uses those bindings to create a div with some text that is appended to the body of the document.

Run npm run build, start a server (perhaps with php -S localhost:3000 in a new console tab) at the root of the project, and then navigate to http://localhost:3000 to see our newly-created DOM element:

The takeaway is that having to work with the DOM in this way is really tedious. It's hard to type DOM APIs due to JavaScript's dynamic nature. For example, Element.innerText is used both to get and set an element's innerText, depending on how it's used, which therefore would result in two different type signatures:

[@bs.get] external getInnerText: Dom.element => string = "innerText";
[@bs.set] external setInnerText : (Dom.element, string) => unit = "innerText";

Luckily, we have React, which largely abstracts the DOM for us. Using React, we don't need to worry about typing the DOM APIs. It's nice to know that when we want to interact with various browser APIs, BuckleScript has the tools we need to get the job done. While it's certainly possible to write frontend web applications in pure Reason, it's a much more pleasant experience when using ReasonReact, especially when first getting started with Reason.

主站蜘蛛池模板: 玛沁县| 宣武区| 固始县| 波密县| 洛宁县| 盐源县| 长宁县| 内黄县| 绥滨县| 嘉善县| 乌兰浩特市| 剑川县| 澄迈县| 疏勒县| 新沂市| 乌海市| 北海市| 轮台县| 吉木乃县| 巴南区| 北碚区| 藁城市| 麻城市| 瓮安县| 宜君县| 墨玉县| 壶关县| 海口市| 大港区| 招远市| 卓尼县| 新巴尔虎右旗| 甘肃省| 玉门市| 武义县| 河池市| 尼玛县| 克东县| 青川县| 钟祥市| 临沭县|