TL;DR:
これは、要求された 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
は単なる関数です。たまたま反応コンポーネントを受け取って返す関数であり、これは少し不思議ですが、実際には他のものと同じように単なる値です。通常の関数のようにバインドできます。
このような単純なものでも機能します
[@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
、2 つの関数を備えたモジュールが必要で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
(これについては、@idkjs 経由で @bloodyowl に感謝します)。
module StrongMessage = {
include HelloMessage;
let make = withStrong(make);
}
なかなかいいですね。などinclude HelloMessage
からエクスポートされたすべての定義が含まれるため、これは機能しますが、その他のものも含まれます。これはおそらく、この方法でコンポーネントをラップするときに必要なことですが、それが必要でない場合に備えて、含まれているモジュールからすべてをインポートおよび再エクスポートすることに注意してください。HelloMessage
makeProps
make
使用法
最後に、バインディングと JSX の両方を用意したら、次のように使用できます。
ReactDOMRe.renderToElementWithId(
<StrongMessage name="Joe" />,
"react-app"
);