2

I want to work with Redux/React in Kotlin.js, but I only found Redux/React libraries for Android (such as redux-kotlin).

whalemare
  • 1,107
  • 1
  • 13
  • 30
dilvan
  • 2,109
  • 2
  • 20
  • 32

2 Answers2

4

With Kotlin/JS you don't need "libraries" in a usual sense, you just need to tell compiler how to work with React. In order to do this, you should write a set of external declarations and may be annotate them with special JS platform annotations (it' much like writing d.ts file in TypeScript). See these links: JavaScript interop, Module systems.

You can look at following project: kotlin-wrappers. However, author claims it's in a very early stage. Another useful project is kotlin-fullstack-sample, which shows how to use React with Kotlin.

Also, you can generate React declarations for Kotlin using ts2kt tool. It's also a bit incomplete and does not always produce proper declarations, you'll have to manually fix errors.

Finally, you can fall back to dynamic type. It's the fastest option to start using React, but with dynamic you won't get any benefit from Kotlin type system.

Note that with Kotlin you can't use JSX. You can use type-safe builders instead, for example, kotlinx.html library.

Alexey Andreev
  • 1,980
  • 2
  • 17
  • 29
  • 1
    I am aware that it's possible to write a React wrapper. But I would prefer not to do it myself. I would rather use a library like clojurescript's Re-frame or scala's Diode. – dilvan Oct 06 '17 at 11:03
  • 1
    I ended up calling the react.js library directly. It means some work to write the interface, but Kotlin is very good at javascript interoperation. – dilvan Oct 22 '17 at 15:00
  • This all has changed and now completely obsolete. – Egor Okhterov Dec 24 '19 at 12:30
1

You need to write type wrappers for redux:

external interface ReduxState
external class Store {
    @JsName("getState")
    fun getState(): ReduxState

    @JsName("dispatch")
    fun dispatch(action: dynamic)
}

@JsModule("redux")
@JsNonModule
external object Redux {
    @JsName("createStore")
    fun <ST : ReduxState> createStore(reducer: (ST, dynamic) -> ReduxState,
                                      initialState: ST,
                                      enhancer: (dynamic) -> ST = definedExternally)
            : Store

    @JsName("applyMiddleware")
    fun applyMiddleware(vararg middleware: () -> (dynamic) -> dynamic)
            : ((dynamic) -> Unit, () -> ReduxState) -> Unit

    @JsName("compose")
    fun compose(vararg funcs: dynamic): (dynamic) -> dynamic
}

And for react-redux

@file:JsModule("react-redux")

package ktypings.redux

import react.RClass
import react.RProps
import react.ReactElement


@JsName("connect")
external fun <P : RProps, ST : ReduxState> connect(
    mapStateToProps: ((ST, P) -> P)? = definedExternally,
    mapDispatchToProps: (((dynamic) -> Unit, P) -> P)? = definedExternally
): (Any) -> RClass<P>

@JsName("Provider")
external val Provider: RClass<ProviderProps>

external interface ProviderProps : RProps {
    var store: Any
}

in order to use them from your kotlin code. You can see example project here https://github.com/ShyykoSerhiy/kotlin-react-redux-material

shyyko.serhiy
  • 486
  • 2
  • 10