I’m working on the new syntax for jsx spread props in the PR. https://github.com/rescript-lang/syntax/pull/517 I’ve reached a new design of react ppx through the discussion with @cristianoc and I’ve designed the new react ppx output as per his suggestion. It is based on the more general type checking of the structural typings feature RFC: More general type checking for structural typings - #50 by tsnobip I think it is much cleaner implementation and closed to js-react in terms of interface. What do you guys think?
JSX
module Foo = {
@react.component
let make = (~id, ~name) => {
<div> {id->React.string} {name->React.string} </div>
}
}
@react.component
let make = () => {
<>
<div id="1" onClick={_ => ()}> {`div`->React.string} </div>
<Foo id="2" name=`Foo` />
</>
}
As-is
module Foo = {
@obj
external makeProps: (~id: 'id, ~name: 'name, ~key: string=?, unit) => {"id": 'id, "name": 'name} =
""
let make =
(@warning("-16") ~id, @warning("-16") ~name) => {
ReactDOMRe.createDOMElementVariadic("div", [{id->React.string}, {name->React.string}])
}
let make = {
let \"V3$Foo" = (\"Props": {"id": 'id, "name": 'name}) =>
make(~name=\"Props"["name"], ~id=\"Props"["id"])
\"V3$Foo"
}
}
@obj external makeProps: (~key: string=?, unit) => {.} = ""
let make = () => {
ReactDOMRe.createElement(
ReasonReact.fragment,
[
ReactDOMRe.createDOMElementVariadic(
"div",
~props=ReactDOMRe.domProps(~id="1", ~onClick={_ => ()}, ()),
[{`div`->React.string}],
),
React.createElement(Foo.make, Foo.makeProps(~id="2", ~name=`Foo`, ())),
],
)
}
let make = {
let \"V3" = (\"Props": {.}) => make()
\"V3"
}
To-be
module Foo = {
@obj
type make<'id, 'name> = {
id: 'id,
name: 'name,
key: option<string>,
}
let make = ({id, name, key}: make<'id, 'name>) => {
ReactDOMRe.createDOMElementVariadic("div", [{id->React.string}, {name->React.string}])
}
}
@obj type make = {key: option<string>}
let make = ({key}: make) => {
ReactDOMRe.createElement(
ReasonReact.fragment,
[
ReactDOMRe.createDOMElementVariadic(
"div",
~props={id: Some("1"), onClick: Some({_ => ()})},
[{`div`->React.string}],
),
Foo.make({id: "2", name: `Foo`}),
],
)
}
EDIT:
Keep the lowercase in v3 style to avoid the changes in the @rescript/react
bindings.
@obj type make = {key: option<string>}
let make = ({key}: make) => {
ReactDOMRe.createElement(
ReasonReact.fragment,
[
ReactDOMRe.createDOMElementVariadic(
"div",
~props=ReactDOMRe.domProps(~id="1", ~onClick={_ => ()}, ()),
[{`div`->React.string}],
),
Foo.make({id: "2", name: `Foo`}),
],
)
}