Patrick Doyle
Patrick Doyle

Reputation: 1

Android Compose wont update state from Mutable State

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

  1. Using delegates with the by keyword and importing the setValue compose extension functions.
  2. Moving the mutableStateOf to a remember function in the compose block

Upvotes: 0

Views: 273

Answers (2)

Patrick Doyle
Patrick Doyle

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

chuckj
chuckj

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

Related Questions