Mr. Goldberg
Mr. Goldberg

Reputation: 101

Kotlin multiplatform js react - how to use redux Store Provider?

While using kotlin-multiplatform/js with react-redux, after the release, old way of setting-up the Redux Store Provider is deprecated (and may work only in kotlin-react-legacy lib). It was not easy to understand the new way of using it, because of lack of documentation and code examples. So here it is the working example)

The old way:

import react.dom.render
import react.router.dom.*
import react.redux.provider
import react.RBuilder
import redux.createStore
import redux.rEnhancer
import kotlinx.browser.document

fun main() {
    val rootDiv = document.getElementById("root")!!
    render(rootDiv) {
        provider(store) { // this: {RBuilder}
            app()
        }
    }
}

fun RBuilder.App() = { ... }

val store = createStore(::reducer, 0, rEnhancer())

fun reducer(state: Int = 0, action: Any): Int {
    return when (action) {
        is Increment -> state + 1
        is Decrement -> state - 1
        else -> state
    }
}

class Increment : RAction
class Decrement : RAction

Upvotes: 0

Views: 232

Answers (1)

Mr. Goldberg
Mr. Goldberg

Reputation: 101

The new way, with Function Components and ChildrenBuilder:

import kotlinx.browser.document
import react.create
import react.dom.client.createRoot
import react.redux.Provider
import react.FC
import react.Props
import react.dom.html.ReactHTML.h1
import react.redux.useDispatch
import react.redux.useSelector
import redux.*

fun main() {
    val container = document.getElementById("root") ?: error("Couldn't find root container!")
    createRoot(container).render(Provider.create { // this: {ChildrenBuilder & Props & ProviderProps}
        store = masterStore // Set the store. Because it is named ProviderProps.store, you can't use name 'store' for your store any more.
        App {}
    })
}

val App = FC<Props> {

    // Subscribe to store updates
    val count = useSelector { state: Int -> state }

    // Make changes to a store
    // WrapperAction type is here because of rEnhancer
    val dispatch = useDispatch<Any, WrapperAction>()

    h1 {
        +"Counter ${count}"
        onClick = {
            dispatch(Increment())
        }
    }
}

val masterStore = createStore(::reducer, 0, rEnhancer())

/* Reducer stays the same */

Upvotes: 0

Related Questions