[Call for help #2] Test JSX v4

The PR to fix is on review. https://github.com/rescript-lang/syntax/pull/666

1 Like

It looks like there may be an issue when not using the transform and using the external keyword.

type props<'msg> = {msg: 'msg}
@module("@foo/bar")
external make: props<_> => React.element = "SomeComponent"

Gets compiled to

JsxRuntime.jsx(
  (function (prim) {
    return Bar.SomeComponent(prim);
  }),
  { msg: "test" }
)

instead of

JsxRuntime.jsx(Bar.SomeComponent, {
  msg: "test"
})

Thanks for reporting.
This code seems an interface. Can you give me a sample example that is compiled?
Confused. I’ll look into it.

For more context the external component I’m binding to uses forwardRef, which returns an “exotic” component that is not callable.

interface ExoticComponent<P = {}> {
  /**
   * **NOTE**: Exotic components are not callable.
   */
  (props: P): (ReactElement|null);
  readonly $$typeof: symbol;
}

What you really end up with is an object with a render method.

Is this anothet report? Do you want to bind a component which is implemented with forwardRef?

If it is, you can bind the component which is implemented with forwardRef:

@module("componentForwardRef") @react.component
  external make: (~x: string, ~ref: ReactDOM.Ref.currentDomRef) => React.element = "component"

In order to bind to the component without JSX transformation, I think this is the proper way:

type props<'msg> = {msg: 'msg}
@module("@foo/bar")
external make: React.component<props<'msg>> => React.element = "SomeComponent"

With JSX transformation

@module("@foo/bar") @react.component
external make: (~msg:'msg) => React.element = "SomeComponent"

Thanks @moondaddi, the following worked

type props<'msg> = {msg: 'msg}
@module("@foo/bar")
external make: React.component<props<'msg>> = "SomeComponent"
1 Like