Skip to content

Commit 12d4c08

Browse files
committedMay 5, 2023
fix JSX to adopt to change of React.fragment type
1 parent 5afd83e commit 12d4c08

File tree

6 files changed

+53
-27
lines changed

6 files changed

+53
-27
lines changed
 

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
- Remove unnecessary require and import statements when using dynamic imports. https://github.com/rescript-lang/rescript-compiler/pull/6232
2222
- Fix option unboxing logic in the presence of untagged variants. https://github.com/rescript-lang/rescript-compiler/pull/6233
2323
- Fix printing of local module with type. https://github.com/rescript-lang/rescript-compiler/issues/6212
24+
- Adapting JSX4 to React.fragment's children type change (`'children` -> `React.element`) https://github.com/rescript-lang/rescript-compiler/pull/6238
2425

2526
#### :nail_care: Polish
2627

‎docs/JSXV4.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ function has the name of the enclosing module/file.
358358
// is transformed to
359359
360360
// v4
361-
ReactDOMRe.createElement(ReasonReact.fragment, [comp1, comp2, comp3])
361+
React.createElement(React.fragment, {children: [comp1, comp2, comp3]})
362362
363363
// v4 @ new jsx transform
364364
React.jsxs(React.jsxFragment, {children: [comp1, comp2, comp3]})

‎jscomp/syntax/src/reactjs_jsx_v4.ml

+35-16
Original file line numberDiff line numberDiff line change
@@ -1358,28 +1358,43 @@ let expr ~config mapper expression =
13581358
in
13591359
let childrenExpr = transformChildrenIfList ~mapper listItems in
13601360
let recordOfChildren children =
1361+
(* FIXME: missing loc *)
13611362
Exp.record [(Location.mknoloc (Lident "children"), children)] None
13621363
in
1363-
let args =
1364-
[
1365-
(nolabel, fragment);
1366-
(match config.mode with
1367-
| "automatic" -> (
1368-
( nolabel,
1369-
match childrenExpr with
1370-
| {pexp_desc = Pexp_array children} -> (
1371-
match children with
1372-
| [] -> emptyRecord ~loc:Location.none
1373-
| [child] -> recordOfChildren child
1374-
| _ -> recordOfChildren childrenExpr)
1375-
| _ -> recordOfChildren childrenExpr ))
1376-
| "classic" | _ -> (nolabel, childrenExpr));
1377-
]
1364+
let applyReactArray expr =
1365+
Exp.apply
1366+
(Exp.ident
1367+
{txt = Ldot (Lident "React", "array"); loc = Location.none})
1368+
[(Nolabel, expr)]
13781369
in
13791370
let countOfChildren = function
13801371
| {pexp_desc = Pexp_array children} -> List.length children
13811372
| _ -> 0
13821373
in
1374+
let transformChildrenToProps childrenExpr =
1375+
match childrenExpr with
1376+
| {pexp_desc = Pexp_array children} -> (
1377+
match children with
1378+
| [] -> emptyRecord ~loc:Location.none
1379+
| [child] -> recordOfChildren child
1380+
| _ -> (
1381+
match config.mode with
1382+
| "automatic" -> recordOfChildren @@ applyReactArray childrenExpr
1383+
| "classic" | _ -> emptyRecord ~loc:Location.none))
1384+
| _ -> (
1385+
match config.mode with
1386+
| "automatic" -> recordOfChildren @@ applyReactArray childrenExpr
1387+
| "classic" | _ -> emptyRecord ~loc:Location.none)
1388+
in
1389+
let args =
1390+
(nolabel, fragment)
1391+
:: (nolabel, transformChildrenToProps childrenExpr)
1392+
::
1393+
(match config.mode with
1394+
| "classic" when countOfChildren childrenExpr > 1 ->
1395+
[(nolabel, childrenExpr)]
1396+
| _ -> [])
1397+
in
13831398
Exp.apply
13841399
~loc (* throw away the [@JSX] attribute and keep the others, if any *)
13851400
~attrs:nonJSXAttributes
@@ -1390,7 +1405,11 @@ let expr ~config mapper expression =
13901405
Exp.ident ~loc {loc; txt = Ldot (Lident "React", "jsxs")}
13911406
else Exp.ident ~loc {loc; txt = Ldot (Lident "React", "jsx")}
13921407
| "classic" | _ ->
1393-
Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOM", "createElement")})
1408+
if countOfChildren childrenExpr > 1 then
1409+
Exp.ident ~loc
1410+
{loc; txt = Ldot (Lident "React", "createElementVariadic")}
1411+
else
1412+
Exp.ident ~loc {loc; txt = Ldot (Lident "React", "createElement")})
13941413
args)
13951414
(* Delegate to the default mapper, a deep identity traversal *)
13961415
| e -> default_mapper.expr mapper e

‎jscomp/syntax/tests/ppx/react/expected/fragment.res.txt

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
@@jsxConfig({version: 4, mode: "classic"})
22

3-
let _ = ReactDOM.createElement(React.fragment, [])
4-
let _ = ReactDOM.createElement(React.fragment, [ReactDOM.createDOMElementVariadic("div", [])])
5-
let _ = ReactDOM.createElement(
3+
let _ = React.createElement(React.fragment, {})
4+
let _ = React.createElement(
65
React.fragment,
6+
{children: ReactDOM.createDOMElementVariadic("div", [])},
7+
)
8+
let _ = React.createElementVariadic(
9+
React.fragment,
10+
{},
711
[ReactDOM.createDOMElementVariadic("div", []), ReactDOM.createDOMElementVariadic("div", [])],
812
)
9-
let _ = ReactDOM.createElement(React.fragment, [ReactDOM.createElement(React.fragment, [])])
13+
let _ = React.createElement(React.fragment, {children: React.createElement(React.fragment, {})})
1014
let _ = React.createElement(Z.make, {})
1115
let _ = React.createElement(Z.make, {children: ReactDOM.createDOMElementVariadic("div", [])})
1216
let _ = React.createElement(
@@ -36,7 +40,7 @@ let _ = React.jsx(React.jsxFragment, {})
3640
let _ = React.jsx(React.jsxFragment, {children: ReactDOM.jsx("div", {})})
3741
let _ = React.jsxs(
3842
React.jsxFragment,
39-
{children: [ReactDOM.jsx("div", {}), ReactDOM.jsx("div", {})]},
43+
{children: React.array([ReactDOM.jsx("div", {}), ReactDOM.jsx("div", {})])},
4044
)
4145
let _ = React.jsx(React.jsxFragment, {children: React.jsx(React.jsxFragment, {})})
4246
let _ = React.jsx(Z.make, {})

‎jscomp/syntax/tests/ppx/react/expected/noPropsWithKey.res.txt

+4-3
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ module V4C = {
2222
type props = {}
2323

2424
let make = (_: props) =>
25-
ReactDOM.createElement(
25+
React.createElementVariadic(
2626
React.fragment,
27+
{},
2728
[
2829
JsxPPXReactSupport.createElementWithKey(~key="k", V4CA.make, {}),
2930
JsxPPXReactSupport.createElementWithKey(~key="k", V4CB.make, {}),
@@ -63,10 +64,10 @@ module V4C = {
6364
React.jsxs(
6465
React.jsxFragment,
6566
{
66-
children: [
67+
children: React.array([
6768
React.jsxKeyed(V4CA.make, {}, ~key="k", ()),
6869
React.jsxKeyed(V4CB.make, {}, ~key="k", ()),
69-
],
70+
]),
7071
},
7172
)
7273
let make = {

‎jscomp/syntax/tests/ppx/react/expected/removedKeyProp.res.txt

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module Foo = {
1414
module HasChildren = {
1515
type props<'children> = {children: 'children}
1616

17-
let make = ({children, _}: props<_>) => ReactDOM.createElement(React.fragment, [children])
17+
let make = ({children, _}: props<_>) => React.createElement(React.fragment, {children: children})
1818
let make = {
1919
let \"RemovedKeyProp$HasChildren" = (props: props<_>) => make(props)
2020

@@ -24,8 +24,9 @@ module HasChildren = {
2424
type props = {}
2525

2626
let make = (_: props) =>
27-
ReactDOM.createElement(
27+
React.createElementVariadic(
2828
React.fragment,
29+
{},
2930
[
3031
JsxPPXReactSupport.createElementWithKey(~key="k", Foo.make, {x: "x", y: "y"}),
3132
React.createElement(Foo.make, {x: "x", y: "y"}),

0 commit comments

Comments
 (0)