Managing State in Jetpack Compose

Learn the differences between stateless and stateful composables and how state hoisting can help make your composables more reusable. By Rodrigo Guerrero.

5 (2) · 1 Review

Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Implementing the Register and Clear Buttons

Open RegisterUserComposables.kt and add these parameters to RegistrationFormScreen(), below onFavoriteAvengerChanged:

onRegisterClicked: (User) -> Unit,
onClearClicked: () -> Unit

In this code, you added the buttons’ callbacks.

Now, update the two buttons within RegistrationFormScreen() like this:

OutlinedButton(
  onClick = {
    // 1.
    onRegisterClicked(
      User(
        username = registrationFormData.username,
        email = registrationFormData.email,
        favoriteAvenger = registrationFormData.favoriteAvenger,
        likesStarWars = registrationFormData.isStarWarsSelected
      )
    )
  },
  modifier = Modifier.fillMaxWidth(),
  // 2.
  enabled = registrationFormData.isRegisterEnabled
) {
  Text(stringResource(R.string.register))
}
OutlinedButton(
  // 3.
  onClick = { onClearClicked() },
  modifier = Modifier
    .fillMaxWidth()
    .padding(top = 8.dp)
) {
  Text(stringResource(R.string.clear))
}

In this code, you:

  1. Create a User object and pass it to onRegisterClicked().
  2. Set the enabled state to the register button.
  3. Execute onClearClicked() when the user clicks the clear button.

Next, open MainActivity.kt and update the call to RegistrationFormScreen() with these parameters, adding them below onFavoriteAvengerChanged:

// 1.
onClearClicked = formViewModel::onClearClicked,
// 2.
onRegisterClicked = { user ->
  formViewModel.onClearClicked()
  mainViewModel.addUser(user)
  navController.popBackStack()
}

In this code, you:

  1. Execute onClearClicked() when you tap the button for clearing.
  2. Add the user creation code: Function for clearing the form, adding the user and navigating back to the main screen.

Build and run. Open the registration screen and register a user, like in this image:

Stateless Registration Form

Click the register button. You’ll navigate back to the user list, but the user is still not there. You’ll fix that next.

Fixing the Users List

In MainActivity.kt, modify UserListScreen() to receive a list of users as parameter, like this:

@Composable
fun UserListScreen(
  navController: NavController,
  users: List<User>
)

Here, UserListScreen() receives the list of registered users. The MainViewModel is the state handler that holds the users list.

In UserListScreen(), pass the users list to UserList():

UserList(users)

With this, you provide UserList() with the state needed to show the list of users.

In onCreate(), below navController, create a state variable that will hold the users list:

val users by mainViewModel.users.observeAsState(emptyList())

users is a LiveData that you’ll observe as state and assign an empty list as default value.

Finally, four lines below, pass the users state variable to UserListScreen() as follows:

UserListScreen(navController, users)

Build and run. Add and register a new user. You’ll see the user in the list on the main screen, like in the next image:

Users List

Amazing! You’ve added state to your screens and made the app work and become a pro in creating and modifying composables. Congratulations!

Where to Go From Here?

Download the final project by using the Download Materials button at the top or bottom of the tutorial.

To learn more about Jetpack Compose, watch the Jetpack Compose video course. You can also find more information in our Jetpack Compose by Tutorials book.

Finally, Android Animations by Tutorials has an excellent section on animations in Jetpack Compose.

I hope you enjoyed this tutorial on managing state in Jetpack Compose. Please join the forum discussion below if you have any questions or comments.