State in Jetpack Compose

Rasul Aghakishiyev
ProAndroidDev
Published in
4 min readAug 4, 2021

--

All Android apps display state to the user. A few examples of state in Android apps:

  • Show AlertDialog when some work is done
  • All animations that appears in application
  • Open or close NavigationDrawer or BottomSheet

Today we will learn how to store our app state in Jetpack Compose.

As you know Jetpack Compose is a declarative framework that uses composable functions to render UI. This means that to update the state of an app we should call a composable function with new arguments. For example, we need to show update the greeting text according to users input

@Composable
fun GreetingBox() {
Column {
Text(text = "Hello, ")
OutlinedTextField(value = "", onValueChange = {

}
)
}
}

So if we run this composable, we will see that we cannot write in our TextField.

That’s because we set the constant value to TextField and on every recomposition, our text will be empty. You maybe think that we can create some variable that will store our text and then pass to the TextField value. Let’s try this and see what happens.

@Composable
fun GreetingBox() {
var username = ""
Column {
Text(text = "Hello, $username")
OutlinedTextField(value = username, onValueChange = {
username = it
}
)
}
}

The result was the same. Jetpack Compose doesn’t recompose our function with a new value because it didn’t know that state changed. For this purpose, we have mutableStateOf that converts our value to the state that Jetpack Compose will handle.

@Composable
fun GreetingBox() {
var username by mutableStateOf("")

Column {
Text(text = "Hello, $username")
OutlinedTextField(value = username, onValueChange = {
username = it
}
)
}
}

If write code like this android studio will show warning:

Creating a state object during composition without using remember

As we mentioned Jetpack Compose recompose functions whenever the state changes. This means that the username object will be recreated on every recomposition. In our case when the value in TextField changes and Jetpack Compose recompose our GreetingBox.

To avoid this problem we need to store the value somewhere that is free from recomposition which will save its state despite recomposition. For this purpose in Jetpack Compose, we have remember. It will store the value during the composition.

After this updates our code will look like this:

@Composable
fun GreetingBox() {
var username by remember {
mutableStateOf("")
}
Column {
Text(text = "Hello, ")
OutlinedTextField(value = username, onValueChange = {
username = it
}
)
}

And now whenever users input change, our username will notify the system that its state changed and this composable should be recomposed with a new value. As the result, our username variable always will be with the latest input that the user entered.

Additionally

To store our data, we can also use ViewModel from Architecture Components. ViewModels also free from the lifecycle of Jetpack Compose and will be a perfect fit for this. Now our code looks like this.

class GreetingViewModel : ViewModel() {
private val _userName = MutableLiveData("")
val userName: LiveData<String> = _userName
fun onNameChange(input: String) {
_userName.value = input
}
}


@Composable
fun GreetingBox(
vm: GreetingViewModel = viewModel()
) {
val username = vm.userName.observeAsState()
Column {
Text(text = "Hello, ${username.value}")
OutlinedTextField(
value = username.value!!,
onValueChange = vm::onNameChange
)
}
}

Run code and we will see that everything also works fine:

Conclusion

Today we learned to how learned how to save states in Jetpack Compose.
To store values in Composable functions free from recomposition we always must use remember. Also, ViewModel will be the perfect choice to save data because it is attached to an Activity lifecycle instead of composable

Feel free to follow me on Twitter and don’t hesitate to ask questions related to Jetpack Compose.

Twitter : https://twitter.com/a_rasul98

Thanks for reading, and see you later!

--

--

Android Software Engineer. Interested in mobile development. In love with Jetpack Compose