Writing functional components with Kotlin/JS for React is great but requires a bit of boilerplate which makes each new component require some setup. Most of this boilerplate is extremely simple, perfect for automation.
Consider the following example React functional component written with Kotlin/JS:
private external interface HelloProps : RProps {
var name: String
}
private val HELLO_COMPONENT = rFunction<HelloProps> { props ->
+"Hello, ${props.name}"
}
fun RBuilder.Hello(name: String) {
HELLO_COMPONENT.invoke {
attrs.name = name
}
}Now consider the following, free of boilerplate:
fun RBuilder.Hello(name: String) {
+"Hello, $name"
}This is really nice and clean! Because it is not (currently) a React component, it cannot take advantage of React hooks. With the Kotlin compiler plugin provided by this library, making this function a React component is as simple as adding an annotation! (and Gradle dependency stuff)
@RFunction
fun RBuilder.Hello(name: String) {
+"Hello, $name"
}The compiler plugin automatically generates the RProps interface and functional component RClass. It then rewrites the original function to invoke the component, automatically assigning all the component attributes. Magic!
This library is a work in progress and requires using Kotlin/JS IR backend for compilation and often requires a specific version of Kotlin as well. The Kotlin/JS IR backend is currently in preview and is not recommended for production. Use at your own risk!
| Kotlin Version | Plugin Version |
|---|---|
| 1.4.10 | 0.2.1 |
| 1.4.20 | 0.3.0 |
| 1.4.30 | 0.4.0 |
See the sample directory for a working project using this compiler plugin which is also available live.
Builds of the Gradle plugin are available through the Gradle Plugin Portal.
plugins {
kotlin("jvm") version "1.4.30"
id("com.bnorm.power.kotlin-react-function") version "0.4.0"
}Annotations are available via Maven Central:
implementation("com.bnorm.react:kotlin-react-function:0.4.0")Make sure Kotlin/JS is configured to compile using IR!
kotlin {
js(IR) {
// ...
}
}To set the key of a React functional component, use the @RKey annotation on a
single parameter to a @RFunction annotated function.
@RFunction
fun RBuilder.ListItem(@RKey item: Item) {
...
}This uses the toString() value of the annotated parameter as the key for the
component. If the value of the key needs to be controlled more explicitly, mark
an unused parameter as the key.
@RFunction
fun RBuilder.Component(... other parameters ..., @RKey key: String) {
// `key` doesn't need to be used to be set as the key of the component
}If the @RKey annotated parameter is null, then the string "null" will be
set as the component key. It is also possible to use default parameters to
derive the key from another parameter.