Skip to content

Latest commit

 

History

History
103 lines (89 loc) · 2.91 KB

File metadata and controls

103 lines (89 loc) · 2.91 KB

ComposeWithRedux

a android jetpack compose demo, use redux-kotlin manage app state

By using ksp + kotlinpoet, I implemented this proposal :Make easy to 'register' reducers

It has a small amount of code and simple functions, but it can help us combine sliceReducer very well

import dependencies:

  1. Add the ksp plugin to the build.gradle file in the root directory
  plugins {
      id 'com.google.devtools.ksp' version '1.6.21-1.0.6' apply false
  }
  1. Use the ksp plugin in the module and add dependencies
plugins {
  id 'com.google.devtools.ksp'
}
android {
  kotlin {
    sourceSets {
        // Let the IDE recognize the code generated by KSP
        main.kotlin.srcDirs += 'build/generated/ksp'
    }
  }
}
ksp {
  // configure the ksp output directory
  arg("target", "com.example.composewithredux.redux")
}
dependencies {
  implementation project(':compose-redux')
  implementation project(':redux-kotlin-annotation')
  ksp project(':redux-kotlin-processor')
}

Usage:

@SliceReducer("areas")
val areaReducer = reducerForActionType<List<Area>, AreaAction> { state, action ->
    when (action) {
        is AreaAction.AddArea -> {
            state + action.area
        }
        is AreaAction.DelArea -> {
            state.filter {
                it.id != action.id
            }
        }
    }
}

@SliceReducer("name")
fun nameReducer(state: String, action: Any): String? {
    return when (action) {
        is NameAction.Rename -> action.name
        is NameAction.ClearName -> ""
        else -> state
    }
}

We only need to annotate the reducer function with @SliceReducer, and then execute build to automatically generate a complete AppState and rootReducer, the automatically generated files are like this:

// Generated by KSP
package com.example.composewithredux.redux

import kotlin.Any
import kotlin.String
import kotlin.collections.List

public data class AppState(
  public val areas: List<Area>,
  public val name: String,
)

public fun rootReducer(state: AppState, action: Any): AppState = AppState(
   areas = areaReducer(state.areas, action),
   name = nameReducer(state.name, action),
)

In the end, we only need to create a store instance through the createThreadSafeStore function:

val store = createThreadSafeStore(
    ::rootReducer, AppState(
        areas = listOf(
            Area(id = "1", name = "beijing"),
            Area(id = "2", name = "shanghai"),
            Area(id = "3", name = "guangzhou")
        ),
        name = "junerver",
    )
)

This code is unavoidable, because The initial state is required for a ReduxKotlin store, so we need to provide the initial state manually.

Thanks to kotlin's named parameters, even if we add a new sliceReducer function later, we can maintain this initial state through named parameters.