Open shadaj opened 6 years ago
static contextType
will be awesome! Currently, we have several wrapper components whose sole purpose is to grab a context value and pass it as a prop to the underlying component (so that the underlying component can use it in componentDidMount
and such lifecycle methods).
The remaining two features are generally pretty incompatible with Scala (typing) / Scala.js (dynamic imports), so going to close this issue for now.
@shadaj I'm wondering does it make sense to reopen this for enabling React.lazy
now that Scala.js has supported code-splitting for a while?
My slinky app is starting to get slooow, so I was hoping to use React.lazy presuming scalajs-bundler can handle the extra bundles it generates! Would you still consider this improvement?
@shadaj any words of wisdom how I could go about contributing a react Lazy support? Where in the code base might I refer to for how similar functionality is implemented? I'm not sure what your schedule is, but I don't think there's any other way to progressively load a slinky app other than enabling this feature so I might give it a try since I'm in desperate need!
Thanks for reopening :)
@shadaj where I'm a bit stuck implementing a facade for lazy
is that it requires the return of a module
with default export, not simply a ReactElement
. Using Scala.JS dynamicImport
, do you have a hunch or any tips on how to signify that type? A module is just a file, so does it mean literally the bundled file path (a string?)?
Okay, I think I have a working implementation of lazy
that at least compiles. But I can't run it since scalajs-bundler doesn't yet support multiple outputs! @shadaj have you found a way around this?
Here's what I got so far:
trait LazyResult[P] extends js.Object {
val default: FunctionalComponent[P]
}
@js.native
@JSImport("react", JSImport.Namespace, "React")
object ReactShim extends js.Object {
final def `lazy`[P](f: js.Function0[js.Promise[LazyResult[P]]]): FunctionalComponent[P] = js.native
}
The only awkward bit is the props require you to explicitly instantiate the case class
, but other than that it's not too ugly:
@react
object App {
type Props = Unit
val other = ReactShim.`lazy`(() => js.dynamicImport(new LazyResult[Other.Props]{
override val default = Other.component
}))
val component = FunctionalComponent[Props] { props =>
val (show, setShow) = useState[Boolean](false)
div(
"Hey!",
button(onClick := (() => setShow(true))),
if (show) {
other(Other.Props("hello"))
} else {
Nil
}
)
}
}
React.memo
(more generally, explore functional component support?)React.lazy
(deferred indefinitely, does this have meaning in Scala.js where bundle splitting does not exist?)static contextType
(deferred indefinitely due to complex typing requirements, ping me if you need this!)static getDerivedStateFromError
(in 0.5.1)Suspense
component (in 0.5.1)