Jetpack Compose: State Management
In this article we created a guideline that can help you understand the state concept in android, why do we need state and how do we manage state in compose.
State in Software Development
If you encounter with finite state machines before, you already have an idea about state.
But if you didn’t, don’t worry you will learn what is the meaning of the state for software development:

Finite State Machine
In given diagram “before, inside, after” are the states of the finite state machine and similarly in software development we have states of our application which changes according to user input, data, sensors and so on.
Is State Necessary For Android?
Having a state in android application is inevitable. If we take a look at android’s state definition:
State in an app is any value that can change over time. This is a very broad definition and encompasses everything from a Room database to a variable on a class.
Like android says, it almost covers everything about android application! For example:
- If a button makes a color change when it clicked, it has to hold a state about whether it clicked or not.
- If you want to show a toast message when network request returned success, you need to have a state about the network request status.
In the end, yes having a state is necessary for android and you have to manage it somehow.
State Management In Android
Before Jetpack Compose, Android developers where using viewModels and Saved Instance States as an option for managing and storing application’s user interface states.
To make it more clear we can give an example:
Let’s say user is in register screen and has to type the code that sent to given email address.
If we don’t store(manage) the data that user typed in a state:
When user opens gmail from recent apps to get last digit of the code and comes back to register screen, all digits will be gone from register screen.
But if we store the typed data into viewModel in onPause() and restore it in onResume() we will manage our state successfully.
State and Lifecycle
We talked about onPause() and onResume() methods which are related to activity/fragment lifecycle. That means there must be a set of rules for states and a relationship between the application lifecycles’ and the states:

The Activity Lifecycle
- State must be reactive to lifecycle events. (ex. Clear state in onDestroy)
- State must not extend it’s scope. (Storing the state even if the corresponding screen is not alive)
- State must not cause memory leaks.
State management in Jetpack Compose
Android claims that: “Jetpack Compose helps you be explicit about where and how you store and use state in an Android app.” So let’s see how we do state management in jetpack compose:
In our previous article we mentioned that jetpack compose is declarative, so only way to update it is by calling again with new arguments. So when user enter characters into textfield we have to call our composable again with typed characters.
Let’s take a look at the android’s sample code:
@Composable
fun HelloContent() {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = "Hello!",
modifier = Modifier.padding(bottom = 8.dp),
style = MaterialTheme.typography.h5
)
OutlinedTextField(
value = "",
onValueChange = { },
label = { Text("Name") }
)
}
}When this code runs, textfield doesn’t update itself. We need to update value parameter to observe changes in user interface.
Note: Key terms that defined by android:
- Composition: a description of the UI built by Jetpack Compose when it executes composables.
- Initial composition: creation of a Composition by running composables the first time.
- Recomposition: re-running composables to update the Composition when data changes.
If you want to get more detail about recomposition it is explained in this article.
So in order to fix textfield’s bug, we have to store our state and trigger recomposition each time when our state changes.
Remember Key Word
Jetpack compose can use remember api to store state(any object in particular) at initial composition and value will be available on recompositions. If we rewrite our code with remember:
@Composable
fun HelloContent() {
Column(modifier = Modifier.padding(16.dp)) {
var name by remember { mutableStateOf("") }
if (name.isNotEmpty()) {
Text(
text = "Hello, $name!",
modifier = Modifier.padding(bottom = 8.dp),
style = MaterialTheme.typography.h5
)
}
OutlinedTextField(
value = name,
onValueChange = { name = it },
label = { Text("Name") }
)
}
}Now each time user enters character, variable name will be updated. Name variable is a mutableStateOf String which used with remember API. Recomposition will trigger when state that used by composable function changes and since it covered with remember new value won’t be lost in recomposition.
Note: If we want to store our state in configuration changes as well (such as scren rotation), we must use rememberSaveable API.
Jetpack Compose supports common observable types for android:
Stateful and Stateless
Whenever a composable function stores state with remember it becomes stateful. This makes composable harder to test and reuse. However, if a composable follows state hoisting it will be open for testing and reusability. Both approaches are meaningful in their own context.
ViewModel as State Source of Truth
There are multiple source of truth approaches for jetpack compose states: Composables, State holders and ViewModels. In this article we talk about viewModels as state source of truth:
ViewModels are good for state source of truth because:
- They access to business logic and prepare data for user interface.
- ViewModels have longer lifetime than composables.
Conclusion
In this article, we explained what is state, why it is needed for android, how do we manage state in android and compose. We also talked about remember API, stateful and stateless concepts and finally, viewModel as state source of truth.
What’s Next?
There are:



