a android jetpack compose demo, use redux-kotlin manage app state
通过使用 ksp + kotlinpoet,实现了这个提案:Make easy to 'register' reducers
它的代码量很少,实现的功能也很简单,但是可以很好的帮助我们组合 sliceReducer
在模块中引入:
- 在根目录的
build.gradle
文件中添加 ksp 插件
plugins {
id 'com.google.devtools.ksp' version '1.6.21-1.0.6' apply false
}
- 在模块中使用ksp插件,并添加依赖
plugins {
id 'com.google.devtools.ksp'
}
android {
kotlin {
sourceSets {
// 让IDE识别KSP生成的代码
main.kotlin.srcDirs += 'build/generated/ksp'
}
}
}
ksp {
// 配置 ksp 输出目录
arg("target", "com.example.composewithredux.redux")
}
dependencies {
implementation project(':compose-redux')
implementation project(':redux-kotlin-annotation')
ksp project(':redux-kotlin-processor')
}
基础使用方法:
@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
}
}
我们只需要通过 @SliceReducer
来注解 reducer 函数,然后执行 build
,就可以自动的生成完整的 AppState
与 rootReducer
,自动生成的文件就像这样:
// 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),
)
最终我们只需要通过 createThreadSafeStore
函数生成 store 实例即可:
val store = createThreadSafeStore(
::rootReducer, AppState(
areas = listOf(
Area(id = "1", name = "beijing"),
Area(id = "2", name = "shanghai"),
Area(id = "3", name = "guangzhou")
),
name = "junerver",
)
)
这段代码是无法避免的,因为 redux-kotlin 被设计为必须要给与初始状态,所以我们需要手动提供初始状态。
得力于 kotlin 的命名参数,即使后续我们增加了新的 sliceReducer 函数,也可以通过命名参数来维护这个初始状态。