I am trying to write some extra scalajs-react documentation but I am confused.
It says here :
A
ReactElement
is aReactDOMElement
or a React component.
But it says here:
type ReactElement = ReactComponentElement | ReactDOMElement;
Which one is true ?
How can one explain this contradiction ?
How can ReactComponent
and ReactComponentElement
be the same ?
I am confused. Can someone please unconfuse me ?
Perhaps I'm over simplifying, but the source code indicates that a ReactElement is a javascript object with the properties of a ReactNode and key
and ref
properties. I wouldn't put as much stock in the vDom / scaladoc comments. They exist to provide a hint to the user, not the compiler. It's trying to say "ReactElement is the common base trait to ReactComponentElement and ReactDomElement", which you can see is indeed true.
/** ReactElement = ReactComponentElement | ReactDOMElement */
@js.native
trait ReactElement extends Object with ReactNode {
def key: UndefOr[String] = js.native
def ref: UndefOr[String] = js.native
}
/** A React virtual DOM element, such as 'div', 'table', etc. */
@js.native
trait ReactDOMElement extends ReactElement {
def `type`: String = js.native
def props : Object = js.native
}
/** An instance of a React component. Prefer using the subtype ReactComponentU instead. */
@js.native
trait ReactComponentElement[Props]
extends ReactElement
with HasProps[Props]
The key thing here is that React is a a fairly dynamic javascript framework, so in order to add type safety around it scala.js there end up being a number of "similar but not identical" subtypes create to handle the various underlying states. For instance, ReactComponentU
and friends and ReactComponent
/ReactComponentElement
.
I think in order to document it (more?) successfully than it already has been, you probably will have to document React itself, and then paper over it with the type system -- trying to explain things strictly in terms of the scala.js interface is likely to be quite confusing.