Every Android codebase reaches the same fork in the road. Two screens need the same piece of data, and someone has to decide where it lives.
Hoisting only goes so far
State hoisting is the first tool everyone reaches for, and it is the right call right up until the state has to survive a process death. At that point you are no longer hoisting, you are persisting, and those are different problems wearing the same hat.
class PuzzleViewModel(
private val repo: PuzzleRepository,
) : ViewModel() {
val state = repo.observe()
.stateIn(viewModelScope, Eagerly, Loading)
}
If two screens disagree about the truth, the bug is not in either screen. It is in the fact that you let them each keep a copy.
Three rules that held up
- State lives in the longest-lived scope that reads it.
- Two copies of the truth is a bug, never an optimisation.
- If it must survive process death, it belongs on disk.
What changed in practice
I rebuilt Mathrid's grid state around this rule and deleted about four hundred lines. Nothing changed for players. It simply stopped having two opinions about what had been typed.