evergreen
evergreen

Reputation: 763

android compose recomposition with data class

I have question about compose concept.

I have data class like below

data class Sample(var num1: Int)

......

class SampleViewModel: ViewModel() {
   var sampleData by mutableStateOf(Sample(num1 = 0))

fun onChange(newNum: Int) {
   sampleData.num1 = newNum
}
}

and when i make compose function like below

@Composable
fun TestFunc(num1: Int, onChange: (Int) -> Unit) {
   Button(value = num1, onClick = { onChange(num1 + 1) })
}

compose doesn't know the change of 'sampleData's num1'

i need to use 'copy method' of data class [sampleData = sampleData.copy(newNum)]
if i need to trigger recomposition

but if sampleData have more than one propoerties and also there are many composable functions use properties and are showed on same screen
there is all recomposition everywhere you use values of sampleData

so i change the code like bellow.

@Composable
fun TestFunc(num1: Int, onChange: (Int) -> Unit) {
   var value by remember { mutableStateOf(num1) }
   Button(value = value, onClick = { onChange(it) })
}

If i use like this, recomposition exists, num1 is changed
but maybe memory needs more, and i can't sure this code is stateless

what do you think about this code and if this is not good, could you tell me better solution?

Upvotes: 1

Views: 4839

Answers (1)

Ben Trengrove
Ben Trengrove

Reputation: 8749

Compose will only recompose when the outer most object changes in your MutableState. It cannot detect changes to inner parts of that class, like var variables. In general you want to have your data class be immutable and then pass in new versions of it each time.

The simplest way of implementing what you have would be as follows:

data class Sample(val num1: Int)

class SampleViewModel: ViewModel() {
   var sampleData by mutableStateOf(Sample(num1 = 0))
      private set

   fun onChange(newNum: Int) {
      sampleData = sampleData.copy(num1 = newNum)
   }
}

Upvotes: 3

Related Questions