How to apply State Management and State Hoisting in Jetpack Compose Apps

If you are a beginner to Jetpack compose, understanding and applying State Management and State Hoisting can be challenging!

Compose is declarative and as such the only way to update it is by calling the same composable with new arguments. These arguments are representations of the UI state. Any time a state is updated a recomposition takes place.

Composable functions can store a single object in memory by using the remember composable. A value computed by remember is stored in the Composition during initial composition, and the stored value is returned during recomposition.

The simplest way to declare a MutableState object in composable is:

var value by remember { mutableStateOf(default) }

I have created two sample apps at my GitHub account. These two apps are very simple, single screen and only focus on State Management concept and its application.

Please check out JetUserProfile and JetBMICalculator.

JetUserProfile

This is a sample app (for beginners-App #1). It demonstrates how compose manages state with a Boolean State.

Jet User Profile
Jet User Profile

Here, the state of Button click (isClicked) toggles each time button is clicked. UI for Vertical List — “Showing profiles” is driven by State of Button.

//1.Define boolean to hold state
var isClicked by remember { mutableStateOf(false) }
//2.Toggle state on Button Click
Button
(
onClick = { isClicked = !isClicked },
) {
Text(text = "Profile")
}
//3. Profile Entries are shown based on State
//Recomposed on Button click
if (isClicked) {
Profile(getProfileEntries())
}

JetBMICalculator

This is a sample app (For beginners App #2) demonstrates the concept of State Hoisting in Jetpack Compose.

State hoisting in Compose is a pattern of moving state to a composable’s caller to make a composable stateless.

Jet BMI Calculator
Jet BMI Calculator

In JetBMICalculator app, there are two forms on the screen and hence two composables for the same.
Top: BMI Calculator Form
Bottom: BMI Result Form

MainContent() {    //state - showBmiResult and bmiResult     BMICalculatorForm (//state - Height and Weight)
BMIResultForm()
}

Height and Weight are the two states used by BMI Calculator form composable, however these are local to this composable. Hence not hoisted by parent composable (MainContent()). Only when Calculate button is clicked, latest value is passed via onClick.

However, other two states — showBmiResult and bmiResult — are modified by actions inside BMICalculatorForm(), but are used by BMIResultForm() to display on UI. Hence both of these are hoisted by their parent composable (MainContent()).

You may download or clone the GitHub repos for the complete source code.

Links:

JetUserProfile

JetBMICalculator

If you are a beginner to Jetpack compose, take some clues from JetBMICalculator app and try developing some calculator on your own.

It would help to gain confidence in developing compose way — to work on real world complex apps.

Happy Coding! Compose Way :)

Bhavna is a Freelance Android developer, Android TE/FPE/Video Instructor @raywenderlich. Youtuber - LearnAndroid