表示に使ってよいのは UiState だけ
ViewModel を介して Unidirectional data flow を実現する。

Composable は UiState を collectAsState して得た情報のみを表示する。UiState 以外の ViewModel のメソッド/プロパティの返り値を表示したり条件分岐の条件にしてはいけない。
この一線を守らないと、画面の状態が UiState とそれ以外に分散し、「いま何が表示されているか」が型から読めなくなる。
UiState と ViewModelState を分ける
ViewModel には2つの状態を置く。
- UiState — UI の状態を表現する interface。Composable Function から参照しやすい形にしてある
- ViewModelState — ViewModel 内部で管理する状態。
toUiState()で UiState に変換する
内部の都合をそのまま画面に流さず、変換を1箇所に置くことで、Composable が受け取る形を安定させられる。
UiState は Sealed Interface にする
UiState を Sealed Interface にして、Post がない/あるときにそれぞれ必要な情報だけを持たせる。nullable な情報は持たせない。
Composable 側では when でスマートキャストして参照する。
これは 想定外の状態は型で表現できなくする を UI 層でやっているのと同じことで、状態の取りうる形を型で列挙してしまえば、Composable 側の分岐漏れはコンパイラが教えてくれる。
接続点の話は ViewModel に触れるのは Route だけにする に書いた。