Compose 状态state 笔记

9 阅读1分钟

在compose中,可以使用mutableState 创建可观察的对象,为了让可观察数据在compose函数重组后依旧可以保持最新。可以使用remember api 将数据存储在内存中

三种写法:

    val mutableState = remember { mutableStateOf("") }
    val value by remember { mustableStateOf("") }
    val {value,setValue}  = remember { mustableState{""} }

注意:如果要对list进行可变重组,需要使用mustateStateListOf(...),可以对增删改进行重组。如果是mustateListOf(list(...)),可以对list整个重新赋值进行重组。

与 ViewModel 结合,将列表状态提升到 ViewModel 中,与UI逻辑分离。

class TodoViewModel : ViewModel() {
   // 在ViewModel中使用可观察的StateFlow
   private val _todos = MutableStateFlow<List<TodoItem>>(emptyList())
   val todos: StateFlow<List<TodoItem>> = _todos.asStateFlow()

   fun addTodo(text: String) {
       _todos.update { currentList ->
           currentList + TodoItem(
               id = Random.nextInt(),
               text = text,
               isDone = false
           )
       }
   }
}

@Composable
fun TodoScreen(viewModel: TodoViewModel = viewModel()) {
   // 在Compose中收集StateFlow
   val todoList by viewModel.todos.collectAsStateWithLifecycle()

   Column {
       LazyColumn {
           items(todoList) { item ->
               TodoItemView(item)
           }
       }
       // 通过ViewModel更新状态
       Button(onClick = { viewModel.addTodo("New Task") }) {
           Text("Add")
       }
   }
}

性能优化:避免不必要的重组

对于大型列表,使用 derivedStateOf 或 remember 计算派生值,避免在每次重组时都重新计算。

@Composable
fun TodoSummary(todos: List<TodoItem>) {
    // 仅当todos变化时,才重新计算已完成的数量
    val completedCount by remember(todos) {
        derivedStateOf {
            todos.count { it.isDone }
        }
    }

    Text("已完成: $completedCount / ${todos.size}")
}