JetpackComposeで状態変化が画面に反映されない書き方

JetpackComposeに触れる中でViewModelに保持させた状態の変化が画面に即時で反映されない場合があったのでそのコードを記します。

package jp.kawagh.learn_recompose

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel

data class UiState(val a: Int, var b: Int)

class MyViewModel : ViewModel() {
    var uiState by mutableStateOf(UiState(0, 0))
        private set

    fun incA() {
        // recompose
        uiState = uiState.copy(a = uiState.a + 1)
    }

    fun incB() {
        // not recompose
        uiState.b += 1
    }

}

上記コードのコメントにも書かれていますがincBメソッドを呼んだ場合には(状態の更新は起こるが)画面に状態の更新は反映されません。

状態が画面に即時で反映されて欲しいケースがほとんどだと思うので、incBのような書き方はそもそもコンパイルの段階でエラーで弾けるように data classのメンバの定義は以下のようにvarではなくvalを使おうと思っています。

- data class UiState(val a: Int, var b: Int)
+ data class UiState(val a: Int, val b: Int)

そもそもdata classの定義としてvarを使うことになっていたのはUiStateといったdata classでまとめる前に下のように書いていた名残でした。

    var b by mutableStateOf(0)
        private set

リファクタリングしたつもりで画面と状態更新のズレを生じさせてしまっていました。 UIテストでないと検知出来ない部分で再びハマりそうなので書き残しておきます。