-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[react] Component and Builder APIs need cleanup #358
Comments
I know the team is busy and all right now but, I just wanted to say, I know this is a breaking change but it is a necessary one. Please please lets solve this once and for all |
@andylamax that's why I've started my own wrapper: |
Yes, we haven't enough time now, and i know that it's necessary, but you still can make PRs to help us. |
@fluidsonic First of all, thank you for your review. We performed a lot of work to improve our API after your notes and I will try to analyze results.
We introduced
We tried to align with Typescript typings for React, we reduced R-naming and added some missing concepts
We tried to simplify API and implement all common functionality using
Right now we are working on CSS improvement and thinking about reincarnation of CSS-in-JS solution in wrappers. But now there are much less difficulties with types system because again we have After all I propose to close this issue and open a new one if there are additional suggestion for improvements. |
When I've started working with kotlin-react I've had a lot of confusion because the API is not consistent nor easy to understand.
To name a few:
styled
as HOC for functional components.Status quo
I'll go through a collection of inconsistencies that I've noticed.
There are two functions to create functional components that are almost identical:
kotlin-wrappers/kotlin-react/src/main/kotlin/react/RBuilder.kt
Lines 176 to 189 in 10805ef
kotlin-wrappers/kotlin-react/src/main/kotlin/react/ReactComponent.kt
Lines 84 to 91 in 10805ef
A crucial difference is that one returns
RClass<P>
while the other returnsFunctionalComponent<P>
.RClass<P>
andFunctionalComponent<P>
have no common interface and thus cannot be used interchangeably where a component definition is expected.rFunction
above theFunctionalComponent
is even cast toRClass<P>
.RClass
has the omnipresentR
prefix whileFunctionalComponent
does not.That makes it difficult to use API that is made for either one or the other but could easily be used for both, for example:
HOC
operates onRClass
.lazy/rLazy()
operate onRClass
.styled()
operates onRClass
.memo()
operates onFunctionalComponent
.Then there's also
RBuilder.child()
which is inconsistent across overloads:Child
, i.e. not a component but an actual element. The very generic nameChild
is confusing because components are also added as children, but aren't aChild
.Any
and is type-unsafe.handler
is a required parameter.props
is a required parameter.KClass<out Component>
.handler
is a required parameter. Noprops
parameter.reified Component
.handler
is a required parameter. Noprops
parameter.FunctionalComponent
.handler
is an optional parameter.props
is an optional parameter. It's an extension function.RClass
explicitly.It's not much better with
SomeType.invoke()
withinRBuilder
.RClass
.handler
is a required parameter.FunctionalComponent
.handler
shouldn't be needed ifP = RProps
.The distinction between
Component
andRComponent
is also not clear.The bottom line
RClass
,(R)Component
andFunctionalComponent
are related.RBuilder
'schild()
andinvoke()
are defined so inconsistently across different types of component definitions.Ideas for improvement
I suggest starting with cleaning up the type hierarchy. Something along these lines:
RComponentDefinition
.KClass<out RComponentClass>
as we cannot haveKClass<out RComponentClass>
implementRComponentClass
.RState
andRContext
across the entire hierarchy. But that would make the API way more complicated because you'd have to specify 3 generic parameters everywhere. This would benefit hugely from KT-1215 and KT-17061.P
ofRComponentDefinition
probably shouldn't bein
-projected because it also uses it in anout
position (defaultProps
).RBuilder.child()
could be improved like this:RBuilder.invoke()
could be improved like this:There would also have to be a replacement for
KClass<out Component<P, *>>.rClass
to get aRComponentDefinition<P>
instead.Last but not least, let's remove either
rFunction
orfunctionalComponent
and have the remaining one returnRFunctionalComponent<P>
.The text was updated successfully, but these errors were encountered: