繁体   English   中英

Kotlin - StateFlow 不向其收集器发送更新

[英]Kotlin - StateFlow not emitting updates to its collectors

我的应用程序中有一个 UserStateModel(数据类)类型的 StateFlow。

private val _userStateFlow: MutableStateFlow<UserStateModel?> = MutableStateFlow(UserStateModel())
val userStateFlow: StateFlow<UserStateModel?> = _userStateFlow

这是用户状态模型

data class UserStateModel(
    val uid: String? = null,
    val username: String? = null,
    val profileImageUrl: String? = null,
    var isLoggedIn: Boolean = false,
    val isPremiumUser: Boolean = false,
    val posts: List<Post>? = listOf()
) 

当我使用新的用户名更新 StateFlow 时,它会将更改发送给收集器并更新 UI。 但是当我更改帖子中的属性时:列表? 列出它不会发出更改。 当我更改列表的大小时,当我更改索引 0 处的 Post 的 name 属性时,它不会。 如何检测对 Data 类的子属性的更改?

现在我使用一个丑陋的解决方法,我补充说

val updateErrorWorkaround: Int = 0 

到 UserStateModel 数据类并将其增加一,以便收集器得到通知

Ps 我正在使用 MVVM + Clean Architecture 和 Jeptack Compose

编辑那是我的帖子模型:

data class Post(
    val id: Int,
    val name: String, 
    val tags: MutableList<Tag>? = null

)

这是我更新 MutableList 的方法:

val posts = userStateFlow.value?.posts
posts.get(index).tags?.add(myNewTag)
_userStateFlow.value = userStateFlow.value?.copy(posts = posts)

这些更改不会发送给收集器

StateFlow仅在检测到值更改时发出,它忽略用相同数据替换值。 为此,它将先前的值与新的值进行比较。 出于这个原因,我们不应该修改我们已经提供给StateFlow的数据,因为它无法检测到变化。

例如,我们将value设置为User(name=John) 然后我们通过将其name修改为James来改变相同的用户对象,并将value设置为这个“新”用户对象。 StateFlow将“新” User(name=James)与其存储的值(现在也是User(name=James)进行比较,因此它看不到任何变化。

在您的示例中,您创建了UserStateModel的副本,但在内部您重复使用相同的对象并改变它们。 在这种情况下,您向tags添加了一个新项目,并且此更改也影响了旧的UserStateModel ,因此StateFlow不会检测到更改。

要解决此问题,您需要复制所有已更改的数据,并且不要在原地更改任何内容。 使所有数据不可变更安全,因此valList - 这样您就被迫进行复制。 我将tags更改为val tags: List<Tag> = listOf() ,那么您的代码可能如下所示:

val posts = userStateFlow.value?.posts!!.toMutableList()
posts[index] = posts[index].copy(tags = posts[index].tags + myNewTag)
userStateFlow.value = userStateFlow.value?.copy(posts = posts)

在这里,我们不仅创建了UserStateModel的副本。 我们还复制posts列表,我们修改的Post ,我们还复制标签列表。

或者,如果StateFlow的这种行为对您来说更烦人而不是有用,您可以使用SharedFlow ,它不比较值,而只是发出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM