shadaj / slinky

Write Scala.js React apps just like you would in ES6
https://slinky.dev
MIT License
652 stars 57 forks source link

How to render a ReactComponentClass #235

Open evbo opened 5 years ago

evbo commented 5 years ago

In order to call this function, how can I render the ReactComponent it returns?:

@JSImport("rc-slider", JSImport.Default)
@js.native
object Slider extends js.Object {
  def createSliderWithTooltip: js.Function1[ReactComponentClass[TooltipSliderProps], ReactComponentClass[TooltipSliderProps]] = js.native
}

case class TooltipSliderProps(

                  tipFormatter: Double => String,
                  handleStyle: js.Object,
                  tipProps: js.Object

                )

@react object RcSlider extends ExternalComponent {
  type Props = TooltipSliderProps

  override val component = Slider.createSliderWithTooltip(
    RcSlider.asInstanceOf[ReactComponentClass[TooltipSliderProps]]
  )
}

I am rendering this component like so:

RcSlider(
         TooltipSliderProps(
           tipFormatter = (d: Double) => {s"$d hey"},
           handleStyle = js.Object,
           tipProps = js.Object
         )
       )

but it returns the error in the console:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of `ComponentWrapper`.
shadaj commented 5 years ago

What you'll have to do here is separate out the external component to take the component returned by createSliderWithTooltip as a constructor parameter.

class SliderWithTooltip(val component: js.Object) extends ExternalComponent {
  type Props = TooltipSliderProps
}

Then, you could wrap a component as

val mySliderWithTooltip = new SliderWithTooltip(Slider.createSliderWithTooltip(MyTooltipComponent))

and use it as a regular component

div(
  mySliderWithTooltip(TooltipSliderProps(...))
)

It would be great to have docs on this pattern, since it shows up pretty often, so I'll leave this issue open.