Reputation: 1
I am currently trying to use a compose view outside of the MVVM and ViewModels but I cam having a real struggle with state updates.
Currently I have the Compose view rendering correctly and it is referencing the mutableState I created correctly but I cannot get the state to update.
This is my compose and state code. The composable Content function is called from the activity setContent{}
private var userState = mutableStateOf<List<GithubSearchUser>>(listOf())
private var loadingState = mutableStateOf(LoadingState.SUCCESS)
@Composable
fun Content() {
TemplateProjectTheme {
Scaffold(modifier = Modifier.fillMaxSize(),
topBar = {...}) { innerPadding ->
when (loadingState.value) {
LoadingState.SUCCESS -> {
.padding(innerPadding)
.fillMaxSize()) {
GithubUsersList(
users = userState.value,
onItemClick = listUserClickRelay::send,
modifier = Modifier.fillMaxSize()
)
}
}
LoadingState.EMPTY -> {
//more compose code
}
I am updating the user state using a separate function that updates mutable state
fun updateUsers(users: List<GithubSearchUser>) {
this.userState.value = users
}
The compose code correctly reads the initial state but any updates set to the mutable state don't update or trigger a recompose. In the debugger I can see the state being updated but no recompositing is happening. This issue happens for both the user list and loading state.
This is driving me mad for 2 days now.
I have tried multiple things that all failed
Upvotes: 0
Views: 273
Reputation: 1
I had an issue in my dependency injection, there were two compose instances, one being rendered and one being updated.
There was no issue with the state being updated.
Upvotes: 0
Reputation: 29615
The issue is not the code you have above. The issue is most likely in the caller of updateUsers()
. Since you didn't include the code I can only guess. My guess is updateUsers()
is being called with the same instance of a MutableList<T>
that was modified to contain the new state users. Since the mutableStateOf()
receives the same instance of list
every time, it doesn't consider that a change so it doesn't invalidate the readers.
There are two solutions to this. This easiest is to always call updateUsers()
with a new list instead of the list changes instead of the backing list directly. Alternately, you can use a mutableStateListOf()
instead of a mutuableListOf()
.
Upvotes: 1