如何在 Jetpack Compose 中很好地从数据库初始化状态?

How to nicely init state from database in Jetpack Compose?

我有一个带有数据库的 Jetpack Compose(桌面)应用程序,我想根据数据库中的数据显示一些 UI:

val data = remember { mutableStateListOf<Dto>() }

Column {
    data.forEach { /* make UI */ }
}

我的问题是,我应该在什么时候执行我的数据库查询来填充列表?

我可以

val data = remember { mutableStateListOf<Dto>() }
if (data.isEmpty()) data.addAll(database.queryDtos())

需要 isEmpty 检查以防止在重新组合时重新查询,所以这显然不是正确的方法。

另一种选择是

val data = remember { 
    val state = mutableStateListOf<Dto>() 
    state.addAll(database.queryDtos())
    state
}

这样我就不能重用数据库连接,因为它在 remember 块内。查询应该是异步发生的,而不是在这个初始化器中

那么,如何做好呢?

在 Android 中最干净的方法是使用 view model,并在 init 中调用这样的代码。

在Desktop中取决于操作。这个平台的主要好处是没有 Android 配置更改,所以 remember/LaunchedEffect 不会是 re-created.

  1. 如果初始化代码不重,可以运行直接放在里面remember.

    val data = remember { database.queryDtos() }
    

    如果您以后需要更新列表,请添加 .toMutableStateList()

  2. 如果是重物,最好选择LaunchedEffect。它将具有与 remember 相同的生命周期 - 运行 仅在视图第一次出现时包含代码:

    val data = remember { mutableStateListOf<Dto>() }
    LaunchedEffect(Unit) {
        data.addAll(database.queryDtos())
    }