TL;博士:
这应该与请求的 JavaScript 片段完全相同:
[@bs.module ./hoc.js]
external withStrong
: React.component('props) => React.component('props)
= "withStrong";
module HelloMessage = ...
module StrongMessage = {
include HelloMessage;
let make = withStrong(make);
};
ReactDOMRe.renderToElementWithId(
<StrongMessage name="Joe" />,
"react-app"
);
Reason 游乐场上还有一个可运行的示例,其中进行了一些修改以解决没有单独的 JavaScript 文件的问题。
解释如下:
捆绑
withStrong
只是一个功能。它恰好是一个接受并返回一个 react 组件的函数,这有点神秘,但它们实际上就像其他任何值一样只是值。我们可以像绑定普通函数一样绑定它。
即使像这样简单的事情也会起作用
[@bs.module ./hoc.js]
external withStrong : 'a => 'a = "withStrong";
假设您始终确保传入一个组件。但它并不是特别安全,因为您也可以传递任何其他内容,所以让我们尝试使用应该使用的类型系统,将其限制为仅接受反应组件。
ReasonReact源代码说组件有 type component('props)
,所以这就是我们将使用的。
[@bs.module ./hoc.js]
external withStrong
: React.component('props) => React.component('props)
= "withStrong";
在参数和返回类型中使用'props
类型变量意味着我们将它们限制为相同。也就是说,返回的组件将具有与传入的完全相同的 props,这正是我们在这种情况下想要的。
这就是绑定本身的全部内容。我们现在可以像这样使用它:
let strongMessage = withStrong(HelloMessage.make);
不幸的是,这不支持 JSX。要按原样渲染strongMessage
,我们必须编写类似
React.createElementVariadic(strongMessage, { "name": "Joe" }, [||]);
不是很好。所以让我们解决这个问题。
JSX
<StrongMessage name="Joe" />
转换为
React.createElementVariadic(
StrongMessage.make,
StrongMessage.makeProps(~name="Joe", ()),
[||]
);
所以我们需要一个StrongMessage
具有两个功能的模块,make
并且makeProps
符合React.createElementVariadic
. make
只是组件本身,所以这很简单。makeProps
是一个函数,它接受道具作为标记参数终止unit
(因为道具可能是可选的)并返回一个 js 对象。这也恰好是什么[@bs.obj]
,这绝不是巧合。
把这些放在一起,我们得到:
module StrongMessage = {
let make = withStrong(HelloMessage.make);
[@bs.obj]
external makeProps
: (~name: string, unit) => {. "name" string }
= "";
}
就是这样!耶!
附录:快捷方式
好的,所以这个makeProps
功能有点烦人。幸运的是,在我们的案例中,包装组件的 props 与原始组件相同,因此也没有必要,因为StrongMessage.makeProps
将与HelloMessage.makeProps
. 那我们就偷那个吧!现在我们有了
module StrongMessage = {
let make = withStrong(HelloMessage.make);
let makeProps = HelloMessage.makeProps;
}
但我们可以做得更好!通过使用include HelloMessage
我们可以makeProps
完全放弃(感谢@bloodyowl,通过@idkjs,为此)。
module StrongMessage = {
include HelloMessage;
let make = withStrong(make);
}
这很不错,不是吗?这是有效的,因为include HelloMessage
将包括所有导出的定义,HelloMessage
例如makeProps
,make
以及其他任何东西。当您以这种方式包装组件时,这可能是您想要的,但请注意它会从包含的模块导入和重新导出所有内容,以防这不是您想要的。
用法
最后,一旦我们同时拥有绑定和 JSX,我们就可以像这样使用它
ReactDOMRe.renderToElementWithId(
<StrongMessage name="Joe" />,
"react-app"
);