Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 40 additions & 28 deletions docs/jsx.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@
title: JSX
---

Reason comes with the [JSX](https://reasonml.github.io/docs/en/jsx.html) syntax! ReasonReact works very similar to how [the ReactJS JSX transform](https://reactjs.org/docs/introducing-jsx.html) does.
Reason comes with [JSX](https://reasonml.github.io/docs/en/jsx.html) syntax. Enables representation of HTML-like expressions within the language.

reason-react enables [the ReactJS JSX transform](https://reactjs.org/docs/introducing-jsx.html) in Reason.

Since `reason-react.0.12.0`, the JSX transformation currently supports the [New JSX Transform](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html). 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`](https://opam.ocaml.org/packages/reason-react-ppx/) and add `(preprocess (pps reason-react-ppx))` in [`melange.emit or library`](https://dune.readthedocs.io/en/stable/melange.html) stanzas in your `dune` file.

Here's a list of transformations made by the [ppx](https://ocaml.org/docs/metaprogramming):
# What the ppx does

Here's a list of transformations made by the [ppx](https://ocaml.org/docs/metaprogramming).

## Uncapitalized

Expand All @@ -17,27 +25,26 @@ Here's a list of transformations made by the [ppx](https://ocaml.org/docs/metapr
transforms into

```reason
ReactDOM.createDOMElementVariadic(
ReactDOM.jsxs(
"div",
~props=ReactDOM.domProps(~foo=bar, ()),
[|child1, child2|]
);
ReactDOM.domProps(
~children=React.array([|child1, child2|]),
~foo=bar,
(),
)
)
```

which compiles to the JavaScript code:

```js
React.createElement('div', {foo: bar}, child1, child2)
React.jsx('div', {foo: bar, children: [ child1, child2 ] })
```

Prop-less `<div />` transforms into

```reason
ReactDOM.createDOMElementVariadic(
"div",
~props=ReactDOM.domProps(),
[||]
);
ReactDOM.jsx("div", ReactDOM.domProps());
```

Which compiles to
Expand All @@ -49,80 +56,85 @@ React.createElement('div', {})
## Capitalized

```reason
<MyReasonComponent key={a} ref={b} foo={bar} baz={qux}> {child1} {child2} </MyReasonComponent>
<MyReasonComponent ref={b} foo={bar} baz={qux}> {child1} {child2} </MyReasonComponent>
```

transforms into

```reason
React.createElementVariadic(
React.jsxs(
MyReasonComponent.make,
MyReasonComponent.makeProps(
~key=a,
~ref=b,
~foo=bar,
~baz=qux,
~children=React.null,
~children=[|child1, child2|],
()
),
[|child1, child2|]
);
```

which compiles to

```js
React.createElement(
React.jsxs(
MyReasonComponent.make,
{
key: a,
ref: b,
foo: bar,
baz: qux,
children: null,
children: [ child1, child2 ],
},
child1,
child2,
);
```

Prop-less `<MyReasonComponent />` transforms into

```reason
React.createElement(MyReasonComponent.make, MyReasonComponent.makeProps());
React.jsx(
MyReasonComponent.make,
MyReasonComponent.makeProps(),
);
```

which compiles to

```js
React.createElement(MyReasonComponent.make, {});
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 ReasonReact, just like in ReactJS. **Don't** use them as props in your component!
`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](https://react.dev/reference/react/Fragment).

The empty JSX tag `<></>` is shorthand for `<React.Fragment></React.Fragment>`

```reason
<> child1 child2 </>;
```

transforms into

```reason
ReactDOMRe.createElement(ReasonReact.fragment, [|child1, child2|]);
React.jsx(
React.jsxFragment,
ReactDOM.domProps(~children=React.array([|child1, child2|]), ()),
);
```

Which compiles to

```js
React.createElement(React.Fragment, undefined, child1, child2);
React.jsx(React.Fragment, { children: [child1, child2] });
```

## Children

ReasonReact children are **fully typed**, and you can pass any data structure to it (as long as the receiver component permits it). When you write:
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:

```reason
<MyReasonComponent> <div /> <div /> </MyReasonComponent>
Expand Down