Thread
#compose
    Billy Newman

    Billy Newman

    1 year ago
    Hello all, I am having some issues with a recompose not running when replacing an immutable list
    Colton Idle

    Colton Idle

    1 year ago
    @Billy Newman can you edit your post to put the code in this thread please? https://kotlinlang.slack.com/archives/CJLTWPH7S/p1616265877303000
    Billy Newman

    Billy Newman

    1 year ago
    I have a list of objects that is immutable. There is a property that I am using in each object to determine whether or not I want to show the object. The parent composable does the filtering:
    @Composable
    fun Stuff(state: StuffState) {
      val values = state.values?.filter { it.visible == true }
      ...
      ValuesContent(values)
    }
    @Composable
    fun ValuesContent(values: List<Stuff>) {
       values.forEach { stuff ->
          // show stuff here...
       }
    }
    I modify the state in the viewModel by replacing the entire list with a new list.
    val newValues = values.toMutableList() // this should create a new list
    newValues.find { /* update some object */ }?.let {
       it.visible = false
    }
    
    state.values = newValues
    I am pretty sure if a new list is created a recompose should trigger. Is this still true? Something else I am doing wrong?
    @Ravi I get this “Assuming you’re using the data correctly, Compose should just work, and you shouldn’t have to think any more about it”, however that is where I am stuck. I am using an immutable list. and when I replace that list, a recompose is not happening
    Ravi

    Ravi

    1 year ago
    you should consume your
    StuffState
    as State [
    collectAsState
    or
    observeAsState
    ]
    you can use
    snapshotFlow { state.values }.collect { … }
    Billy Newman

    Billy Newman

    1 year ago
    its just a list, not coming from flow or livedata. still does not fully make sense, everything I have read points to using immutable objects. I am using an immutable list, when anything in that list changes I create a new list, far as I can tell a new immutable object, in this case a list should recompose such that UI updates accordingly to not show the filtered values.
    @Composable
    fun HelloContent(name: String) { ... }
    The name string is immutable here, if it changes a recompose will happen to update any views in the HelloContent composable.
    @Composable
    fun HelloContent(names: List<String>) { ... }
    The name list here is immutable as well, if it changes shouldn’t a recompose fire to update the view?
    @Ravi you were of course right, was just having a hard time finding out why, as most on internet are incorrect. Here from official docs: https://developer.android.com/jetpack/compose/state:
    Caution: Using mutable objects such as ArrayList<T> or mutableListOf() as state in Compose will cause your users to see incorrect or stale data in your app.
    
    Mutable objects that are not observable, such as ArrayList<T> or a mutable data class, cannot be observed by Compose to trigger recomposition when they change.
    
    Instead of using non-observable mutable objects, we recommend you use an observable data holder such as State<List<T>> and the immutable listOf().
    Ravi

    Ravi

    1 year ago
    Billy Newman

    Billy Newman

    1 year ago
    Will do, thanks for pointing me down the right path!