Link Search Menu Expand Document

State Management

Building your Store, you can add Handlers to respond to actions and adjust your model accordingly:

val store = object : RootStore<String>("") {
    val append = handle<String> { model, action: String ->
        "$model$action"
    }

    val clear = handle { model ->
        ""
    }
}

Whenever a String is sent to the append-Handler, it updates the model by appending the text to its current model. clear is a Handler that doesn’t need any information to do its work, so the second parameter can be omitted.

Since everything in fritz2 is reactive, most of the time you want to connect a Flow of actions to the Handler instead of calling it directly:

someFlowOfStrings handledBy store.append

Each Store inherits a Handler called update, accepting the same type as the Store as its action. It updates the Store’s value to the new value it receives. You can use this handler to conveniently implement two-way-databinding by using the changes event-flow of an input-Tag, for example:

val store = RootStore<String>("")

render {
    input {
        value = store.data
        changes.values() handledBy store.update
    }
}.mount("target")

changes in this example is a Flow of events created by listening to the Change-Event of the underlying input-element. Calling values() on it extracts the current value from the input. Whenever such an event is raised, a new value appears on the Flow and is processed by the update-Handler of the Store to update the model. Event-flows are available for all HTML5-events. There are some more convenience functions to help you to extract data from an event or control event-processing.

You can map the elements of the Flow to a specific action-type before connecting it to the Handler. This way you can also add information from the rendering-context to the action. You may also use any other source for a Flow like recurring timer events or even external events.

If you need to purposefully fire an action at some point in your code (to init a [Store] for example) use

//action with value inside Store
action(someValue) handledBy someStore.someHandler

//action without value anywhere else
action() handledBy someStore.someHandler

If the content of your Store is not bound anywhere but need its handler’s code to be executed whenever an action is available, you have to explicitly watch() it:

    val store = object : RootStore<Whatever> {
        val printMessage = handle { model ->
            console.log("some message")
            model
        }
    }

    store.data.watch()

Next we will have a look at how to use Lists as a model.


Table of contents


Distributed by an MIT license.