JSX
Reason comes with JSX syntax. Enables representation of HTML-like expressions within the language.
reason-react enables the ReactJS JSX transform in Reason.
Since reason-react.0.12.0, the JSX transformation currently supports the New JSX Transform. JSX functions are imported from react/jsx-runtime. Previous versions of reason-react used the legacy API React.createElement.
Install
To use it, you would need to install reason-react-ppx and add (preprocess (pps reason-react-ppx)) in melange.emit or library stanzas in your dune file.
What the ppx does
Here's a list of transformations made by the ppx.
Uncapitalized
<div foo={bar}> {child1} {child2} </div>
transforms into
ReactDOM.jsxs(
"div",
ReactDOM.domProps(
~children=React.array([|child1, child2|]),
~foo=bar,
(),
)
)
which compiles to the JavaScript code:
React.jsx('div', {foo: bar, children: [ child1, child2 ] })
Prop-less <div /> transforms into
ReactDOM.jsx("div", ReactDOM.domProps());
Which compiles to
React.createElement('div', {})
Capitalized
<MyReasonComponent ref={b} foo={bar} baz={qux}> {child1} {child2} </MyReasonComponent>
transforms into
React.jsxs(
MyReasonComponent.make,
MyReasonComponent.makeProps(
~ref=b,
~foo=bar,
~baz=qux,
~children=[|child1, child2|],
()
),
);
which compiles to
React.jsxs(
MyReasonComponent.make,
{
ref: b,
foo: bar,
baz: qux,
children: [ child1, child2 ],
},
);
Prop-less <MyReasonComponent /> transforms into
React.jsx(
MyReasonComponent.make,
MyReasonComponent.makeProps(),
);
which compiles to
React.jsx(MyReasonComponent.make, {});
The make above is exactly the same make function you've seen in the previous section.
ref and key are reserved in reason-react, just like in ReactJS. Don't use them as props in your component!
Fragment
Fragment lets you group elements without a wrapper node, and return a single element without any effect on the DOM. More details about this in the react documentation: Fragments.
The empty JSX tag <></> is shorthand for <React.Fragment></React.Fragment>
<> child1 child2 </>;
transforms into
React.jsx(
React.jsxFragment,
ReactDOM.domProps(~children=React.array([|child1, child2|]), ()),
);
Which compiles to
React.jsx(React.Fragment, { children: [child1, child2] });
Children
reason-react children are fully typed, and you can pass any data structure to it (as long as the receiver component permits it). When you write:
<MyReasonComponent> <div /> <div /> </MyReasonComponent>
You're effectively passing the array [| <div />, <div /> |] to MyReasonComponent's children. If you pass a single child like so:
<MyReasonComponent> <div /> </MyReasonComponent>
We unwrap this for you automatically to just <div /> instead of an array of a single element.