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){isAreaAction.AddArea->{state + action.area } isAreaAction.DelArea->{state.filter{it.id != action.id } } } } @SliceReducer("name") funnameReducer(state:String, action:Any): String?{returnwhen (action){isNameAction.Rename-> action.name isNameAction.ClearName->""else-> state } }我们只需要通过 @SliceReducer 来注解 reducer 函数,然后执行 build,就可以自动的生成完整的 AppState 与 rootReducer,自动生成的文件就像这样:
// Generated by KSPpackagecom.example.composewithredux.reduximportkotlin.Anyimportkotlin.Stringimportkotlin.collections.Listpublicdata classAppState( publicvalareas:List<Area>, publicvalname:String, ) publicfunrootReducer(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 函数,也可以通过命名参数来维护这个初始状态。