我正在尝试编写一个生成 DOM 元素的 JavaScript 代码,但是是以函数式的方式,因为所有函数都会产生副作用和突变。为了实现这一点,我使用了 IO monad,但我想我仍然不知道如何很好地使用它们......
首先,我使用的是 crocks 库,它提供了大量 ADT 来与函数式 JS 配合使用(我知道有 ramda,但他们不提供 monad)。另外,我使用了一个小模块,它允许我使用组合来声明 DOM 元素。 (https://github.com/queckezz/elementx)
import IO from 'crocks/IO';
const { div, a, h1, h2, ul, li, button } = require('elementx');
const createHeader = div(
h1(
{class: 'title'},
'This is a title'
),
h2(
{class: 'subtitle'},
'This is a subtitle'
),
div(
{class: 'link'},
a(
{href: 'http://github.com'},
'Github'
)
)
);
document.body.appendChild(createHeader);
上面的代码可以工作,但显然不纯粹。我保留了 IO 导入,但我没有使用它,因为我不知道如何在不破坏代码的情况下实现。我知道 IO 必须接收一个函数作为参数,然后它返回 IO(f(x)),但我对如何将它实现到 createHeader 变量和appendChild 感到非常困惑。此外,通过 IO,createHeader 变量在运行时返回一个函数,但appendChild 需要一个 Node 对象。
最佳答案
好吧,我解决了这个问题,主要问题是......我将一个不会产生副作用的函数(如果不附加到 DOM,createHeader 将不执行任何操作)视为不纯的。叹气……我是新手。
唯一不纯粹的部分是附加,正如 bob 在评论中所说。
所以我的解决方案如下:
//append might not be a good name for this action but...
const append = nodeObj => IO(() => {
document.body.appendChild(nodeObj);
})
append(createHeader)
.run();
只有在 IO 被“激活”时才会创建 DOM 元素,从而推迟了副作用。希望这可以帮助其他新手函数式程序员!
关于javascript - 如何使用 IO monad 正确创建 DOM 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55358197/