One of the hot topics of the KotlinConf 2017 keynote in San Francisco was multiplatform development with Kotlin, Kotlin/Native and Kotlin/JS. The latter has been demonstrated using the Kotlin wrappers for React, which allows you to write React apps using Kotlin. This sounds promising, since it allows you to write both (web-based) front- and backends using one language. You may even share code using multiplatform projects, but that is a topic on its own. In this three-part article I’d like to give an introduction to Kotlin-React. I assume that you know React (if not, have a look at this tutorial) and Kotlin.
A couple of years ago Stefan Liebig and me were creating a tiny webapp with the purpose of comparing web technologies: The Giphy Search. It is basically a simple frontend to the Giphy API, so the user can search animated GIFs by entering some search words. Stefan implemented it with Elm and I was using React. So this was the perfect sample for me to start with Kotlin-React, since it is basically the same technology. I started using create-react-kotlin-app, which scaffolds a complete runnable sample application including an IntelliJ project file. You will find the complete source on GitHub, the app itself is hosted via GitHub pages, so give the Giphy Search App a try.
To get an overview let us compare the app component in React…
…with the Kotlin version:
The main distinction between the technologies is that instead of pseudo HTML in JSX, a DSL is used in Kotlin. Structurally the solutions are quite similar: the
app is a component and is itself a composition of (child-) components, like e.g.
giphyList. In React there are three types of components: functional components, class components and stateful (class-) components. The following sections will show the three of them using Kotlin-React.
The simplest way to provide a component in React is a functional component, which is basically just the render function of a component. Let’s start with the
alert component that takes a message attribute and provides a div with bootstrap alert classes. In React this would be this, a simple function that creates some JSX:
I assume that you already have some Kotlin experience and know the way Kotlin implements (internal) DSLs using a builder. Kotlin already provides a builder for producing HTML. In the same way, Kotlin-React provides a
RBuilder for React. Take a look at the Kotlin-React implementation of the alert:
We just add an extension function
alert() to the
RBuilder that uses the builder itself to create a
div with the bootstrap classes as argument. The alert message is provided as a text (-node) using the unary plus operator. That’s it.
Functional components are a perfect match for simple representational UI. Class components on the other side are more complex (you need to create a class instead of simple function), but they may have state and they can participate in the react lifecycle, e.g.
componentWillMount(). There is a another distinction when it comes to tooling: The React Developer Tools shows classes as tags (like e.g.
<GiphyList>), but just the plain content for functional components. In the following screenshot you can see that the alert is just represented by the
Let’s see how the
GiphyList is realized in Kotlin:
Like in React we create a component class with a render function that provides the content. It has also props and may have state. But a significant difference is that there is an interface for the props
GiphyListProps, means the props are typed! As in the functional component, we create an extension function for the
RBuilder. But here it returns a
ReactElement using the
child() function with our class as parameter. The second parameter is a block that is used to setup our props. Again, the props are typed so the compiler can check what we are doing.
Props are used to pass data from parent to child components, but if a component needs to maintain data on its own, you need a stateful component. Its quite common in React to maintain the value of input fields in the state. Means the input field just triggers the component on changes, the component alters the state, and the new state is rendered by React. An example for this is the
SearchBar component, which is a stateful component that maintains the user’s search term input in the component state:
As with props, the state is also typed by providing an interface that extends
RState. The perfect place for setup of the state is the
init() function where the props may be used for initialization. If you want to see a more complex example, have a look at the app component. It holds all the application state like e.g. the loaded and selected giphy, the loading state, and the error message.
The easiest way to get in touch with Kotlin-React is by creating your own sample using create-react-kotlin-app and give it a try. The React extension is quite helpful to structurally match the app with the code. It also allows you to alter the state at runtime, e.g. in the Giphy Search you may toggle the loading state and watch spinner dis-/appear.
This was enough stuff for today, the next part will explain how to integrate external libraries in Kotlin-React.
True success has more components
than one sentence or idea can contain.