Describe state hoisting and its benefits in Compose

Understanding unidirectional data flow in declarative UI.
Move state to the caller, pass value and event lambda down, keep them stateless.
Internal state in reusable composables or calling hoisting boilerplate.
What's really being asked
This question probes whether you understand the core Compose principle that state should live at the appropriate level of the UI tree and that composables should ideally be stateless functions of data. Interviewers want to see that you can separate state ownership from state display, which directly impacts testability, reusability, and unidirectional data flow.
The full answer
First, a crisp definition: state hoisting means moving the state and the logic that mutates it out of the composable and up to its caller. The composable then accepts the current value as a parameter and an event lambda such as onValueChange or onCheckedChange. Second, the why: by making the composable stateless, you gain reusability because the same UI piece can be dropped into different screens with different state sources. Third, testability improves dramatically because you can call the composable in a unit test or preview with simple parameters instead of mocking a ViewModel or Compose runtime. Fourth, you should mention that the caller now owns the single source of truth, which prevents bugs from split state and aligns with declarative UI patterns.
The mistakes people make
Keeping remember or rememberSaveable inside a supposedly reusable component and arguing it is simpler. Suggesting that only ViewModel state needs hoisting while internal UI state can stay anywhere. Claiming hoisting creates too much boilerplate without acknowledging the trade-offs. Confusing state hoisting with lifting state into a ViewModel specifically; hoisting is about caller ownership, which could be a parent composable, a screen-level state holder, or a ViewModel.
What usually comes next
Where should you stop hoisting? The answer is the common ancestor that needs to read or mutate the state, or a screen-level state holder if multiple unrelated composables need it. How does this relate to Compose performance? Stateless composables skip recomposition more predictably when inputs do not change. What about inputs like TextField? You should still hoist the text value even if it feels verbose, because it lets you react to changes, validate input, or drive derived state.
A concrete example
Imagine a custom Toggle composable. A non-hoisted version uses remember { mutableStateOf(false) } internally. A hoisted version accepts isOn: Boolean and onToggle: () -> Unit. The parent owns the boolean, perhaps in a ViewModel or in another composable using remember. Now Toggle can be used in a settings screen, a dialog, or a list item without change. In a screenshot test or preview, you pass true or false directly and tap the lambda to assert behavior.
Interview question
You are building a reusable Toggle composable. Which implementation best reflects state hoisting?
- a.Accept isOn: Boolean and onToggle: () -> Unit, letting the caller own the stateCorrect
- b.Use remember { mutableStateOf(false) } inside Toggle and let it manage its own checked state
- c.Read the checked state from a shared ViewModel that every screen provides
- d.Keep the state inside Toggle using remember and expose an onToggle callback so the parent can observe changes
Why? this is the answer
State hoisting requires the caller to own the state, passing the current value and an event lambda down to the stateless composable. Option D is a common trap: exposing a callback while still holding state internally prevents the parent from controlling the value directly and hurts reusability and testability.
Just read this? Test yourself on what you have been reading.
Read the original → developer.android.com
- #android
- #jetpack-compose
- #state-hoisting
- #ui-architecture
- #declarative-ui
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on android — each one lists the topics its interview covers.
See open roles