This generates a compile error Fatal error: exception Invalid_argument("react.component calls can only be on function definitions or component wrappers (forwardRef, memo).")
Why isn’t this supported? Is there a workaround?
@react.component
let make = (type apple, ~a as _: apple) => <div />
It seems nearly identical to this, which does compile…
@react.component
let make = (~a as _: 'apple) => <div />
My real scenario is more complex - I’m using a first-class module - and I don’t know how to get it to compile without using locally abstract types.
module type QuizType = {
type t
type configuration
let make: configuration => t
let run: t => unit
}
@react.component
let make = (
type configuration,
~quiz as _: module(QuizType with type configuration = configuration),
~configuration as _: configuration,
) => <div />
The following component can be used only if configuration
and QuizType's configuration
are the same.
module type QuizType = {
type t
type configuration
let make: configuration => t
let run: t => unit
}
@react.component
let make = (
~quiz as _: module(QuizType with type configuration = 'configuration),
~configuration as _: 'configuration,
) => <div />
Is this what you require?
Yes, but that won’t compile as soon as you try to unpack the module. The error is “The type of this packed module contains variables.” See “generic” modules - General - ReScript Forum (rescript-lang.org)
@react.component
let make = (
~quiz: module(QuizType with type configuration = 'configuration),
~configuration as _: 'configuration,
) => {
let module(Q) = quiz
let _q = Q.make(configuration)
<div />
}
For a React component, which needs to be a module anyway, I recommend using a normal functor rather than a function which takes a first-class module. To me it looks like the @react.component
PPX doesn’t understand locally abstract types as parameters.
Here is the functor approach. Works pretty well.
module type QuizType = {
type t
type configuration
let make: configuration => t
let run: t => unit
}
module type QuizComponentType = {
type configuration
@react.component
let make: (~configuration: configuration) => React.element
}
module type MakeType = (P: QuizType) =>
(QuizComponentType with type configuration := P.configuration)
module Make: MakeType = (P: QuizType) => {
@react.component
let make = (~configuration: P.configuration) => {
configuration->P.make->P.run
<div />
}
}
module IntQuiz: QuizType with type configuration = int = {
type t = int
type configuration = int
let make = _ => 1
let run = _ => ()
}
module IntQuizComponent = Make(IntQuiz)
let make = () => <div> <IntQuizComponent configuration=3 /> </div>
2 Likes