Hi,
I wonder if it’s possible to partially apply React’s component props. It’s not critical to my work, but I’m just curious if it’s possible and if it’s not, why.
In the JS world, I can define something like this:
const test = (value) => ({ text }) => (
<h3>
{value} - {text}
</h3>
);
And it works just fine.
I got in a situation where it could be handy, but because the RescriptReact component is a module and requires @react.comopnent macro or @obj external makeProps to define such a function.
I prepared an example that doesn’t compile:
module Test = {
module Base = {
@react.component
let make = (~x: int, ~y: int) => <p> {string_of_int(x + y)->React.string} </p>
}
module Partial = {
@react.component
let make = Base.make(~x=2)
}
}
Of course, I could do just let make = (~y) => <Base x y /> but for the sake of solving the riddle, I wonder if Rescript type system allows what I tried to do (but maybe in a different fashion).
I guess it’s hard to do it with the @react.component annotation because we have no control over the prop type. Without the sugar, something like this might work:
module Button = {
@react.component
let make = (~count: int, ~name: string) => {
let times = switch count {
| 1 => "once"
| 2 => "twice"
| n => Belt.Int.toString(n) ++ " times"
}
let msg = name ++ " clickd me " ++ times
<button> {msg->React.string} </button>
}
}
module Partial = {
let makeProps = Button.makeProps(~count=10)
let make = props => {
let name = props["name"]
let count = props["count"]
let msg = name ++ " clickd me " ++ Belt.Int.toString(count)
<button> {msg->React.string} </button>
}
}
let a = <Partial name="test" />
Thanks!
I like both approaches so I don’t know which one I should pick as the solution
Functor seems to be a bit verbose. On the other hand, using strings for object keys always makes me nervous, as “magic strings” are always easy to misspell.
Originally I wanted to build a base wrapper for the Fontawesome library and create “child” components for every icon I would use. Still, I found out that even a wrapper function would be too much boilerplate than just passing props in all places
Object keys may be mispelled, but the compiler would not compile in this case.
Why don’t you write a little JS script that uses a template string with the boilerplate code and generate a .res file out of that? You could probably even access all the possible icons from the library to help you with the automation.