<p>This article is about how to manage the state in Android Jetpack Compose, state hoisting (<span class="devsite-heading" role="heading" aria-level="3">stateless composable</span>), and s<span class="devsite-heading" role="heading" aria-level="3">tateful versus stateless composable.</span></p> 
 
 
 
<h4><span style="color: #000080;"><strong>What is State in Jetpack Compose?</strong></span></h4> 
<p>The state is an object that is connected/subscribed to one or more widgets, contains data, and is eager to update the widgets from that data.</p> 
<p>If there’s any change happens in data, it will update all its subscribed UI widgets. The values of the state are changed at runtime.</p> 
<p>The <strong class="kd jf"><span style="color: #008000;">@ composable function(s)</span> <span style="color: #008000;">recomposes</span> </strong>itself with the new data when the state/object value is updated and doesn’t affect or update the whole UI.</p> 
<p><strong>In Jetpack Compose, the composable are subscribed to a state, and when the value of the state is updated then all the composable who are subscribed to it also update the value.</strong></p> 
<p>For example, three texts are subscribed to a state, and when the value of the state changes, the text in these three would also be updated.</p> 
<p>With Jetpack compose, we can preserve the state of view in major two ways:</p> 
<ul> 
<li>Using <span style="color: #008000;"><strong>remember{}</strong></span>, a composable function that can store a single object in memory, or by using <span style="color: #008000;"><strong>rememberSaveable{}</strong></span>, a composable function to restore your UI state after an activity or process is recreated (for example it happens when the screen is rotated in the Android application). We can manage a simple state of view within a compose function itself.</li> 
<li>Using <strong><span style="color: #008000;">ViewModel</span></strong>, a state holder to separate business logic from UI component. ViewModel has a longer lifecycle than the composition as they are lifecycle-aware components so ViewModel can preserve its state across configuration changes.</li> 
</ul> 
<h4 id="state-in-composables" role="presentation" data-text="State in composables"><span style="color: #000080;"><strong><span class="devsite-heading" role="heading" aria-level="2">remember Composable</span></strong></span></h4> 
<p>The <a href="https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#remember(kotlin.Function0)"><span style="color: #008000;"><strong>remember{}</strong></span></a> can be used to store both mutable and immutable objects. </p> 
<p>A value computed by remember{} is stored in the Composition during <span style="color: #0000ff;"><strong>initial composition</strong></span>, and the stored value is returned during recomposition.</p> 
<p>In each <span style="color: #0000ff;"><strong>recomposition</strong></span>, remember() returns the stored value so the composable can use it. Whenever the stored value has to change, you can update it and remember() will store it. The next time a recomposition occurs, remember() will provide the latest value.</p> 
<p><span style="color: #000080;"><strong>Key Term: </strong></span></p> 
<ul> 
<li><span style="color: #0000ff;"><strong>Composition:</strong></span> a description of the UI built by Jetpack Compose when it executes composables.</li> 
<li><strong><span style="color: #0000ff;">Initial composition:</span></strong> creation of a Composition by running composables the first time.</li> 
<li><strong><span style="color: #0000ff;">Recomposition:</span></strong> re-running composables to update the Composition when data changes.<br /><br /></li> 
</ul> 
<h5><span style="color: #000080;"><strong>Using mutableStateOf()</strong></span></h5> 
<p>To create a state, we need to use <strong><a href="https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#mutableStateOf(kotlin.Any,androidx.compose.runtime.SnapshotMutationPolicy)"><span style="color: #0000ff;">mutableStateOf()</span></a> </strong>function. In this, the state stores the value on execution, and if any composable is subscribed to it, the composable updates the value if there are any changes.</p> 
<p>There are three ways to declare a MutableState object in a composable:</p> 
<p><span style="color: #000000;">1 . val mutableState = remember { mutableStateOf (default) }</span></p> 
<pre>@Composable<br />fun HelloContent() {<br /> Column(modifier = Modifier.padding(16.dp)) {<br /><br /><span style="color: #008000;"><strong> var name = remember { mutableStateOf("") }</strong></span><br /><br /> if (name.value.isNotEmpty()) {<br /> Text(<br /> text = "Hello, $name.value!",<br /> modifier = Modifier.padding(bottom = 8.dp),<br /> style = MaterialTheme.typography.h5<br /> )<br /> }<br /> OutlinedTextField(<br /> value = name.value,<br /> onValueChange = { name.value = it },<br /> label = { Text("Name") }<br /> )<br /> }<br />}</pre> 
<h6> </h6> 
<h6 id="7f74" class="ku kv ii bn kw kx ky kz la lb lc ld le jo lf jp lg jr lh js li ju lj jv lk ll gj"><span style="color: #000080;"><strong>Using Kotlin’s Delegated Property to access the State</strong></span></h6> 
<p><span style="color: #000000;">2 . var value by remember { mutableStateOf(default) }</span></p> 
<p>In Kotlin, there is a feature called Delegated Property, which simply eliminates the need to access the value property every time.</p> 
<pre>@Composable<br />fun HelloContent() {<br /> Column(modifier = Modifier.padding(16.dp)) {<br /><br /><span style="color: #000000;"><strong> //using kotlin's delegate property</strong></span><br /><strong><span style="color: #008000;"> var name by remember { mutableStateOf("") }</span></strong><br /><br /> if (name.isNotEmpty()) {<br /> Text(<br /> text = "Hello, $name!",<br /> modifier = Modifier.padding(bottom = 8.dp),<br /> style = MaterialTheme.typography.h5<br /> )<br /> }<br /> OutlinedTextField(<br /> value = name,<br /> onValueChange = { name = it },<br /> label = { Text("Name") }<br /> )<br /> }<br />}</pre> 
<p><span style="color: #000000;">3. val (value, setValue) = remember { mutableStateOf(default) }</span></p>
<!-- WP QUADS Content Ad Plugin v. 2.0.98.1 -->
<div class="quads-location quads-ad2" id="quads-ad2" style="float:none;margin:0px;">

</div>
 
<pre>@Composable<br />fun HelloContent() {<br /> Column(modifier = Modifier.padding(16.dp)) {<br /><br /><strong><span style="color: #008000;"> val (name, setName) = remember { mutableStateOf("") }</span></strong><br /><br /> if (name.isNotEmpty()) {<br /> Text(<br /> text = "Hello, $name!",<br /> modifier = Modifier.padding(bottom = 8.dp),<br /> style = MaterialTheme.typography.h5<br /> )<br /> }<br /> OutlinedTextField(<br /> value = name,<br /> onValueChange = { setName(it) },<br /> label = { Text("Name") }<br /> )<br /> }<br />}</pre> 
<h6> </h6> 
<h6><span style="color: #0000ff;"><strong>Output:</strong></span></h6> 
<p><img class="alignnone wp-image-3229" src="https://c1ctech.com/wp-content/uploads/2022/05/Screenshot_2022-05-23-17-19-33-465_com.c1ctech.jetpackcomposestateexp1-473x1024.png" alt="" width="294" height="636" /></p> 
<p> ;</p> 
<p><strong>Note: If your device orientation gets changed, the value will reset.</strong></p> 
<p> <img class="alignnone wp-image-3233" src="https://c1ctech.com/wp-content/uploads/2022/05/Screenshot_2022-05-24-12-17-26-382_com.c1ctech.jetpackcomposestateexp1-1024x473.png" alt="" width="594" height="274" /></p> 
<p> ;</p> 
<p>If you want to keep the data even if the activity recreated/orientation change happened, use <strong><span style="color: #0000ff;">&#8220;rememberSavable&#8221;</span></strong>.</p> 
<h4><span style="color: #000080;"><strong>rememberSaveable C</strong></span><span style="color: #000080;"><strong><span class="devsite-heading" role="heading" aria-level="2">omposable</span></strong></span></h4> 
<p>Use <span style="color: #0000ff;"><strong><a style="color: #0000ff;" href="https://developer.android.com/reference/kotlin/androidx/compose/runtime/saveable/package-summary#rememberSaveable(kotlin.Array,androidx.compose.runtime.saveable.Saver,kotlin.String,kotlin.Function0)">rememberSaveable{}</a> </strong></span>to restore your UI state after an activity or process is recreated. RememberSaveable retains state across recompositions. In addition, rememberSaveable also retains state across activity and process recreation.</p> 
<h6><strong><span style="color: #0000ff;">Example:</span></strong></h6> 
<pre>@Composable<br />fun HelloContent() {<br /> Column(modifier = Modifier.padding(16.dp)) {<br /><br /> var name by <span style="color: #008000;"><strong>rememberSaveable</strong></span> { mutableStateOf("") }<br /><br /> println("HelloContent(): $name")<br /><br /> if (name.isNotEmpty()) {<br /> Text(<br /> text = "Hello, $name!",<br /> modifier = Modifier.padding(bottom = 8.dp),<br /> style = MaterialTheme.typography.h5<br /> )<br /> }<br /> OutlinedTextField(<br /> value = name,<br /> onValueChange = { name = it },<br /> label = { Text("Name") }<br /> )<br /> }<br />}</pre> 
<h6><span style="color: #0000ff;"><strong>Output:</strong></span></h6> 
<p><img class="alignnone wp-image-3235" src="https://c1ctech.com/wp-content/uploads/2022/05/Screenshot_2022-05-24-12-14-34-869_com.c1ctech.jetpackcomposestateexp1-473x1024.png" alt="" width="273" height="591" /> <img class="alignnone wp-image-3234" src="https://c1ctech.com/wp-content/uploads/2022/05/Screenshot_2022-05-24-12-14-47-578_com.c1ctech.jetpackcomposestateexp1-1024x473.png" alt="" width="604" height="279" /></p> 
<p> ;</p> 
<h4><span style="color: #000080;"><strong>State Hoisting</strong></span></h4> 
<p>State hoisting in Compose is a pattern of moving state to a composable&#8217;s caller to make a composable stateless.</p> 
<p>The general pattern for state hoisting in Jetpack Compose is to replace the state variable with two parameters:</p> 
<ul> 
<li><strong><span style="color: #0000ff;">value: T:</span> </strong>the current value to display</li> 
<li><strong><span style="color: #0000ff;">onValueChange: (T) ->; Unit:</span></strong> an event that requests the value to change, where T is the proposed new value</li> 
</ul> 
<p>Each composable can have many value parameters and many event callbacks.</p> 
<h6><strong><span style="color: #0000ff;">Example:</span></strong></h6> 
<pre>@Composable<br />fun HelloScreen() {<br /> var name by rememberSaveable{ mutableStateOf("") }<br /><br /> HelloContent(name = name, onNameChange = { name = it })<br />}<br /><br />@Composable<br />fun HelloContent(name: String, onNameChange: (String) ->; Unit) {<br /> Column(modifier = Modifier.padding(16.dp)) {<br /> Text(<br /> text = "Hello, $name",<br /> modifier = Modifier.padding(bottom = 8.dp),<br /> style = MaterialTheme.typography.h5<br /> )<br /> OutlinedTextField(<br /> value = name,<br /> onValueChange = onNameChange,<br /> label = { Text("Name") }<br /> )<br /> }<br />}</pre> 
<p>By hoisting the state out of <span style="color: #008000;"><strong>HelloContent</strong></span>, it&#8217;s easier to reason about the composable, reuse it in different situations, and test. <span style="color: #008000;"><strong>HelloContent</strong></span> is decoupled from how its state is stored. Decoupling means that if you modify or replace HelloScreen, you don&#8217;t have to change how HelloContent is implemented.</p> 
<h4><span style="color: #000080;"><strong>Stateful versus Stateless</strong></span></h4> 
<p>A composable that uses remember to store an object creates an internal state, making the <span style="color: #0000ff;"><strong>composable stateful</strong></span>.</p> 
<p><span style="color: #008000;"><strong>HelloContent</strong></span> is an example of a stateful composable because it holds and modifies its name state internally. This can be useful in situations where a caller doesn&#8217;t need to control the state and can use it without having to manage the state themselves. However, composables with internal state tend to be less reusable and harder to test.</p> 
<p>A <strong><span style="color: #0000ff;">stateless composable</span></strong> is a composable that doesn&#8217;t hold any state. An easy way to achieve stateless is by using <span style="color: #008000;"><strong>state hoisting</strong></span>.</p> 
<p>The stateful version is convenient for callers that don&#8217;t care about the state, and the stateless version is necessary for callers that need to control or hoist the state.</p> 
<p> ;</p> 


