Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 62e66a2

Browse files
committed
Clarify spec of V4 JSX transformations.
Fixes #653
1 parent 61b7d97 commit 62e66a2

File tree

1 file changed

+33
-21
lines changed

1 file changed

+33
-21
lines changed

cli/JSXV4.md

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -207,45 +207,57 @@ let make = () => {
207207

208208
## V4 Spec
209209

210-
This is the specification that decribes how the JSX V4 transformation works.
210+
This is the specification that decribes the two JSX V4 transformations:
211211

212-
### Abbreviation
212+
- For component definition `@react.component let make = ...`
213+
- For component application `<Foo x y />`
213214

214-
The placement of `@react.component` is an abbreviation as described below.
215+
The transformations are optional in that it is possible to write the resulting code manually instead of using them.
215216

216-
### Normal Case
217+
### Pre-transformation for component definition
218+
219+
To simplify the description of component definition, a pre-transformation
220+
is used to move `@react.component` to a place where the actual transformations operate.
221+
222+
#### Normal Case
217223

218224
```rescript
219225
@react.component
220226
let make = (~x, ~y, ~z) => body
227+
```
221228

222-
// is an abbreviation for
229+
is pre-transformed to
223230

231+
```rescript
224232
let make = @react.component (~x, ~y, ~z) => body
225233
```
226234

227-
### Forward Ref
235+
#### Forward Ref
228236

229237
```rescript
230238
@react.component
231239
let make = React.forwardRef((~x, ~y, ref) => body)
240+
```
232241

233-
// is an abbreviation for
242+
is pre-transformed to
234243

244+
```rescript
235245
let make = React.forwardRef({
236246
let fn =
237247
@react.component (~x, ~y) => ref => body
238248
(props, ref) => fn(props, ref)
239249
})
240250
```
241251

242-
### Component Definition
252+
### Transformation for Component Definition
243253

244254
```rescript
245255
@react.component (~x, ~y=3+x, ?z) => body
256+
```
246257

247-
// is converted to
258+
is transformed to
248259

260+
```rescript
249261
type props<'x, 'y, 'z> = {x: 'x, y?: 'y, z?: 'z}
250262
251263
({x, y, z}: props<_>) => {
@@ -257,21 +269,21 @@ type props<'x, 'y, 'z> = {x: 'x, y?: 'y, z?: 'z}
257269
}
258270
```
259271

260-
If there is any type with the same name of `props`, it needs to be renamed to avoid the error of the multiple definitions of the type name.
272+
> Note: this implicit definition of type `props` means that there cannot be other type definitions of `prop` in the same scope, or it will be a compiler error about multiple definitions of the type name.
261273
262-
### Component Application
274+
### Transformation for Component Application
263275

264276
```rescript
265277
<Comp x>
266-
// is converted to
278+
// is transformed to
267279
React.createElement(Comp.make, {x})
268280
269281
<Comp x y=7 ?z>
270-
// is converted to
282+
// is transformed to
271283
React.createElement(Comp.make, {x, y:7, ?z})
272284
273285
<Comp x key="7">
274-
// is converted to
286+
// is transformed to
275287
React.createElement(Comp.make, Jsx.addKeyProp({x}, "7"))
276288
```
277289

@@ -283,13 +295,13 @@ The jsx transform only affects component application, but not the definition.
283295

284296
```rescript
285297
<Comp x>
286-
// is converted to
298+
// is transformed to
287299
React.jsx(Comp.make, {x})
288300
```
289301

290302
```rescript
291303
<div name="div" />
292-
// is converted to
304+
// is transformed to
293305
ReactDOM.jsx("div", { name: "div" })
294306
```
295307

@@ -308,7 +320,7 @@ type domProps = {
308320
```rescript
309321
@react.component (~x: int, ~y: int=?, ~z: int=?) => React.element
310322
311-
// is converted to
323+
// is transformed to
312324
313325
type props<'x, 'y, 'z> = {x: 'x, y?: 'y, z?: 'z}
314326
@@ -319,15 +331,15 @@ Since an external is a function declaration, it follows the same rule.
319331

320332
### Component Name
321333

322-
Use the V3 convention for names, and make sure the generated
334+
The convention for names is the same one used in V3: the generated
323335
function has the name of the enclosing module/file.
324336

325337
### Fragments
326338

327339
```rescript
328340
<> comp1 comp2 comp3 </>
329341
330-
// is converted to
342+
// is transformed to
331343
332344
// v4
333345
ReactDOMRe.createElement(ReasonReact.fragment, [comp1, comp2, comp3])
@@ -336,9 +348,9 @@ ReactDOMRe.createElement(ReasonReact.fragment, [comp1, comp2, comp3])
336348
React.jsxs(React.jsxFragment, {children: [comp1, comp2, comp3]})
337349
```
338350

339-
### Spread props
351+
### Spread props (new feature)
340352

341-
V4 ppx supports the spread props `{...p}`.
353+
V4 introduces support for the spread operator for props: `{...p}`.
342354

343355
```rescript
344356
module A = {

0 commit comments

Comments
 (0)