User types "android" into your search box. That's 7 API calls if you wired it the way I did the first time.
A few months later I shipped a pagination bug where every infinite-scroll fetch flashed a full-screen loader for half a second. And then there was the Settings screen that needed to refresh the Dashboard when the user changed theme — but Settings couldn't import Dashboard without a circular dependency.
These are the three problems I run into on every non-trivial Compose app. Below is the MVVM pattern I've landed on after making each of these mistakes in production.
(If you're new to MVVM with Compose, I covered the basics with a login screen separately . This article assumes you already know the StateFlow + ViewModel shape and goes one layer up.)
The Search Problem Everyone Gets Wrong
Here's how I used to implement search:
// Don't do this searchTextField . addTextChangedListener { text -> viewModel . search ( text . toString ()) // API call on every keystroke!…