aster.cloud aster.cloud
  • /
  • Platforms
    • Public Cloud
    • On-Premise
    • Hybrid Cloud
    • Data
  • Architecture
    • Design
    • Solutions
    • Enterprise
  • Engineering
    • Automation
    • Software Engineering
    • Project Management
    • DevOps
  • Programming
    • Learning
  • Tools
  • About
  • /
  • Platforms
    • Public Cloud
    • On-Premise
    • Hybrid Cloud
    • Data
  • Architecture
    • Design
    • Solutions
    • Enterprise
  • Engineering
    • Automation
    • Software Engineering
    • Project Management
    • DevOps
  • Programming
    • Learning
  • Tools
  • About
aster.cloud aster.cloud
  • /
  • Platforms
    • Public Cloud
    • On-Premise
    • Hybrid Cloud
    • Data
  • Architecture
    • Design
    • Solutions
    • Enterprise
  • Engineering
    • Automation
    • Software Engineering
    • Project Management
    • DevOps
  • Programming
    • Learning
  • Tools
  • About
  • Programming

Jetpack Compose — When Should I Use DerivedStateOf?

  • aster.cloud
  • December 1, 2022
  • 5 minute read

derivedStateOf — a really common question we see is where and when is the correct place to use this API?

The answer to this question is <strong class="ki jk">derivedStateOf {}</strong> should be used when your state or key is changing more than you want to update your UI. Or in other words, derivedStateOf is like distinctUntilChanged from Kotlin Flows or other similar reactive frameworks. Remember that Composables recompose when the Compose state object they read, changes. derivedStateOf allows you to create a new state object that changes only as much as you need.


Partner with aster.cloud
for your next big idea.
Let us know here.



From our partners:

CITI.IO :: Business. Institutions. Society. Global Political Economy.
CYBERPOGO.COM :: For the Arts, Sciences, and Technology.
DADAHACKS.COM :: Parenting For The Rest Of Us.
ZEDISTA.COM :: Entertainment. Sports. Culture. Escape.
TAKUMAKU.COM :: For The Hearth And Home.
ASTER.CLOUD :: From The Cloud And Beyond.
LIWAIWAI.COM :: Intelligence, Inside and Outside.
GLOBALCLOUDPLATFORMS.COM :: For The World's Computing Needs.
FIREGULAMAN.COM :: For The Fire In The Belly Of The Coder.
ASTERCASTER.COM :: Supra Astra. Beyond The Stars.
BARTDAY.COM :: Prosperity For Everyone.

Let’s take a look at an example. Here we have a username field and a button that enables when the username is valid.

/* Copyright 2022 Google LLC.
SPDX-License-Identifier: Apache-2.0 */

var username by remember { mutableStateOf("") }
val submitEnabled = isUsernameValid(username)
Initial state of username and submitEnabled

It starts off empty and so our state is false. Now when the user starts typing, our state correctly updates and our button becomes enabled.

But here is the problem, as our user keeps typing we are sending state to our button over and over again needlessly.

State updates after the user continues typing

This is where derivedStateOf comes in. Our state is changing more than we need our UI to update and so derivedStateOf can be used for this to reduce the number of recompositions.

/* Copyright 2022 Google LLC.
SPDX-License-Identifier: Apache-2.0 */

var username by remember { mutableStateOf("") }
val submitEnabled = remember {
  derivedStateOf { isUsernameValid(username) }
}
Updating the code to use derivedStateOf

Let’s go through the same example again to see the difference.

State updates with derivedStateOf

The user starts typing, but this time our username state is the only one that changes. The submit state just remains true. And of course, if our username becomes invalid. Our derived state correctly updates again.

Now, this example is a bit oversimplified. In a real app, Compose would most likely skip recomposition of the submit composable as its input parameters have not changed.

Read More  6 Steps To Successful Mainframe Modernization

The reality is, the situations when you need derivedStateOf can feel few and far between. But when you do find a case, it can be supremely effective at minimizing recomposition.

Always remember that there needs to be a difference in the amount of change between the input arguments and output result for <strong class="ki jk">derivedStateOf</strong> to make sense.

Some examples of when it could be used (not exhaustive):

  • Observing if scrolling passes a threshold (scrollPosition > 0)
  • Items in a list is greater than a threshold (items > 0)
  • Form validation as above (username.isValid())

FAQs

Now, let’s look at some other commonly asked questions about derivedStateOf.

Does derivedStateOf have to be remembered?

If it is inside a Composable function, yes. derivedStateOf is just like <a class="au li" href="https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#mutableStateOf(kotlin.Any,androidx.compose.runtime.SnapshotMutationPolicy)" target="_blank" rel="noopener ugc nofollow">mutableStateOf</a> or any other object that needs to survive recomposition. If you use it inside a composable function then it should be wrapped in a <a class="au li" href="https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#remember(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function0)" target="_blank" rel="noopener ugc nofollow">remember</a> or else it will be reallocated on every recomposition.

/* Copyright 2022 Google LLC.
SPDX-License-Identifier: Apache-2.0 */

@Composable
fun MyComp() {
  // We need to use remember here to survive recomposition
  val state = remember { derivedStateOf { … } }
}

class MyViewModel: ViewModel() {
  // We don't need remember here (nor could we use it) because the ViewModel is
  // outside of Composition.
  val state = derivedStateOf { … }
}

What’s the difference between remember(key) and derivedStateOf?

Remember with keys of each state and derivedStateOf can seem quite similar at first glance.

/* Copyright 2022 Google LLC.
SPDX-License-Identifier: Apache-2.0 */

val result = remember(state1, state2) { calculation(state1, state2) }
val result = remember { derivedStateOf { calculation(state1, state2) } }

The difference between remember(key) and derivedStateOf is in the amount of recomposition. <strong class="ki jk">derivedStateOf {}</strong> is used when your state or key is changing more than you want to update your UI.

Read More  Convert YUV To RGB For CameraX ImageAnalysis

Take for example enabling a button only if the user has scrolled a LazyColumn.

val isEnabled = lazyListState.firstVisibileItemIndex > 0

firstVisibleItemIndex will change 0, 1, 2 etc as the user scrolls and causes readers to recompose every time it changes. We only care about if it’s greater than 0 or not. There is a difference in the amount of input we have and output we need and so derivedStateOf is used here to buffer out that unnecessary recomposition.

val isEnabled = remember {
derivedStateOf { lazyListState.firstVisibleItemIndex > 0 }
}

Now, let’s say we have an expensive function that calculates something for us with a parameter. We want our UI to recompose any time the output of that function changes (importantly, the function is also idempotent). We use remember with a key here, as our UI needs to update just as much as our key changes. That is, we have the same amount of input and output.

val output = remember(input) { expensiveCalculation(input) }

Do I ever need to use remember(key) and derivedStateOf together? When is this needed?

This is where things get a little tricky. derivedStateOf can only update when it reads a Compose state object. Any other variables read inside derivedStateOf will capture the initial value of that variable when the derived state is created. If you need to use those variables in your calculation, then you can provide them as a key to your remember function. This concept is much easier to understand with an example. Let’s take our isEnabled example from before and expand it to also have a threshold for when to enable the button, rather than 0.

Read More  Fetching Data And Binding It To The UI In The MAD Skills Series
/* Copyright 2022 Google LLC.
SPDX-License-Identifier: Apache-2.0 */

@Composable
fun ScrollToTopButton(lazyListState: LazyListState, threshold: Int) {
  // There is a bug here
  val isEnabled by remember {
    derivedStateOf { lazyListState.firstVisibleItemIndex > threshold }
  }
  
  Button(onClick = { }, enabled = isEnabled) {
    Text("Scroll to top")
  }
}

Here we have a button that enables when a list is scrolled over a threshold. We are correctly using derivedStateOf to remove the extra recomposition, but there is a subtle bug. If the threshold parameter changes, our derivedStateOf won’t take the new value into account as it captures the initial value on creation for any variable that isn’t a compose state object. As threshold is an Int, whatever is the first value that is passed into our composable will be captured and used for the calculation from then on. ScrollToTopButton will still recompose, as its inputs have changed, but as remember without any keys caches across recomposition, it will not reinitialise the derivedStateOf with the new value.

We can see this by looking at the outputs from our code. At first everything is working correctly.

But then a new value (5) for threshold is passed into our composable.

Even though our scrollPosition is less than threshold, isEnabled is still set to true.

The fix here is to add threshold as a key for remember, this will reinitialise our derivedStateOf state anytime threshold changes.

/* Copyright 2022 Google LLC.
SPDX-License-Identifier: Apache-2.0 */

val isEnabled by remember(threshold) {
  derivedStateOf { lazyListState.firstVisibleItemIndex > threshold }
}

Now we can see, when the threshold changes, the isEnabled state correctly updates.

Do I need to use derivedStateOf to combine multiple states together?

Most likely, no. If you have multiple states that are combining together to create a result then you probably want recomposition to happen any time one of them changes.

Take for example a form that takes in a first name and last name and displays a full name.

/* Copyright 2022 Google LLC.
SPDX-License-Identifier: Apache-2.0 */

var firstName by remember { mutableStateOf("") }
var lastName by remember { mutableStateOf("") }

val fullName = "$firstName $lastName"

Here, as our output changes just as much as our input, derivedStateOf is not doing anything and is just causing a small overhead. derivedStateOf also isn’t helping with asynchronous updates, the Compose state snapshot system is dealing with that separately and these calls here are synchronous.

In this case, there is no need for an extra derived state object at all.

/* Copyright 2022 Google LLC.
SPDX-License-Identifier: Apache-2.0 */

var firstName by remember { mutableStateOf("") }
var lastName by remember { mutableStateOf("") }

val fullName = "$firstName $lastName"

Conclusion

To sum up, remember that derivedStateOf is used when your state or key is changing more than you want to update your UI. If you don’t have a difference in the amount of input compared with output, you don’t need to use it.

By Ben Trengrove
Source Android


For enquiries, product placements, sponsorships, and collaborations, connect with us at [email protected]. We'd love to hear from you!

Our humans need coffee too! Your support is highly appreciated, thank you!

aster.cloud

Related Topics
  • Android
  • API
  • derivedStateOf
  • Jetpack Compose
You May Also Like
View Post
  • Architecture
  • Data
  • Engineering
  • People
  • Programming
  • Software Engineering
  • Technology
  • Work & Jobs

Predictions: Top 25 Careers Likely In High Demand In The Future

  • June 6, 2023
View Post
  • Programming
  • Software Engineering
  • Technology

Build a Python App to Alert You When Asteroids Are Close to Earth

  • May 22, 2023
View Post
  • Programming

Illuminating Interactions: Visual State In Jetpack Compose

  • May 20, 2023
View Post
  • Computing
  • Data
  • Programming
  • Software
  • Software Engineering

The Top 10 Data Interchange Or Data Exchange Format Used Today

  • May 11, 2023
View Post
  • Architecture
  • Programming
  • Public Cloud

From Receipts To Riches: Save Money W/ Google Cloud & Supermarket Bills – Part 1

  • May 8, 2023
View Post
  • Programming
  • Public Cloud

3 New Ways To Authorize Users To Your Private Workloads On Cloud Run

  • May 4, 2023
View Post
  • Programming
  • Public Cloud

Buffer HTTP Requests With Cloud Tasks

  • May 4, 2023
View Post
  • Programming
  • Public Cloud
  • Software
  • Software Engineering

Learn About Google Cloud’s Updated Renderer For The Maps SDK For Android

  • May 4, 2023

Stay Connected!
LATEST
  • 1
    Just make it scale: An Aurora DSQL story
    • May 29, 2025
  • 2
    Reliance on US tech providers is making IT leaders skittish
    • May 28, 2025
  • Examine the 4 types of edge computing, with examples
    • May 28, 2025
  • AI and private cloud: 2 lessons from Dell Tech World 2025
    • May 28, 2025
  • 5
    TD Synnex named as UK distributor for Cohesity
    • May 28, 2025
  • Weigh these 6 enterprise advantages of storage as a service
    • May 28, 2025
  • 7
    Broadcom’s ‘harsh’ VMware contracts are costing customers up to 1,500% more
    • May 28, 2025
  • 8
    Pulsant targets partner diversity with new IaaS solution
    • May 23, 2025
  • 9
    Growing AI workloads are causing hybrid cloud headaches
    • May 23, 2025
  • Gemma 3n 10
    Announcing Gemma 3n preview: powerful, efficient, mobile-first AI
    • May 22, 2025
about
Hello World!

We are aster.cloud. We’re created by programmers for programmers.

Our site aims to provide guides, programming tips, reviews, and interesting materials for tech people and those who want to learn in general.

We would like to hear from you.

If you have any feedback, enquiries, or sponsorship request, kindly reach out to us at:

[email protected]
Most Popular
  • Understand how Windows Server 2025 PAYG licensing works
    • May 20, 2025
  • By the numbers: How upskilling fills the IT skills gap
    • May 21, 2025
  • 3
    Cloud adoption isn’t all it’s cut out to be as enterprises report growing dissatisfaction
    • May 15, 2025
  • 4
    Hybrid cloud is complicated – Red Hat’s new AI assistant wants to solve that
    • May 20, 2025
  • 5
    Google is getting serious on cloud sovereignty
    • May 22, 2025
  • /
  • Technology
  • Tools
  • About
  • Contact Us

Input your search keywords and press Enter.