kotlin-react
Kotlin wrapper for React library. Major version number of this wrapper matches that of React itself.
Installation
-
npm i @jetbrains/kotlin-react
-
npm run gen-idea-libs
See the Bintray page for Maven and Gradle installation instructions.
Creating a simple React component with Kotlin
As you might know, the simplest way to define a React component in JavaScript is to write a function. Like this:
import React from 'react';
export function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
Here's what the roughly equivalent Kotlin code looks like:
package hello
import react.*
import react.dom.*
fun RBuilder.hello(name: String) {
h1 {
+"Hello, $name"
}
}
RBuilder
lets you construct your component's markup using
type-safe builders, similarly to JSX.
When writing React code in JavaScript the type annotations for props (via PropTypes
) are optional, but in Kotlin
they are not.
Here's an example of a component defined using a class with a name
property of type String
:
package welcome
import react.*
import react.dom.*
interface WelcomeProps: RProps {
var name: String
}
class Welcome: RComponent<WelcomeProps, RState>() {
override fun RBuilder.render() {
div {
+"Hello, ${props.name}"
}
}
}
fun RBuilder.welcome(name: String = "John") = child(Welcome::class) {
attrs.name = name
}
And here's how we can use this component in another component:
import welcome.*
fun RBuilder.app {
welcome("Jane")
}
Type-safe inline styles
There is no built-in capability for writing inline styles in a type-safe manner. However, it can be done by adding a dependency on kotlin-css and a simple utility function.
var Tag.style: RuleSet
get() = error("style cannot be read from props")
set(value) = jsStyle {
CSSBuilder().apply(value).declarations.forEach {
this[it.key] = when (it.value) {
!is String, !is Number -> it.value.toString()
else -> it.value
}
}
}
fun Tag.style(handler: RuleSet) {
style = handler
}
Declaring static fields and lifecycle methods (contextType, getDerivedStateFromProps(), etc.)
There is currently no easy way to declare static members from Kotlin/JS (see KT-18891), so please do the following instead:
class MyComponent: RComponent<MyComponentProps, MyComponentState>() {
companion object : RStatics<MyComponentProps, MyComponentState, MyComponent, Nothing>(MyComponent::class) {
init {
getDerivedStateFromProps = { props, state ->
// ...
}
}
}
}
Internals
Imports.kt contains type definitions for React. The remaining classes (React.kt and others) provide higher-level APIs on top of that definition.