Skip to content

Instantly share code, notes, and snippets.

@Andrew0000
Last active January 27, 2023 19:14
Show Gist options
  • Save Andrew0000/b5e033c7eca3d5c5c3722e1ac191c590 to your computer and use it in GitHub Desktop.
Save Andrew0000/b5e033c7eca3d5c5c3722e1ac191c590 to your computer and use it in GitHub Desktop.
remember {} with key is same as derivedStateOf
@Composable
fun ATest() {
val frequentlyChangedState = remember { mutableStateOf(0) }
LaunchedEffect(Unit) {
launch {
delay(5000) // delay so you can attach with Layout Inspector if you don't trust logs enough.
while (frequentlyChangedState.value < 10) {
delay(200)
frequentlyChangedState.value++
}
}
}
val valueToDisplay = remember(frequentlyChangedState.value) {
frequentlyChangedState.value / 2
}
Timber.i("test_ ATest outer") // 1 initial composition + 10 recompositions
ATestInner(valueToDisplay)
}
@Composable
fun ATestInner(value: Int) {
Timber.i("test_ ATestInner") // 1 initial composition + 5 recompositions
Text(text = "value: $value")
}
@bentrengrove
Copy link

Inner is being skipped because the value hasn't changed. With derivedStateOf it wouldn't even have to evaluate whether to skip it or not. There is a subtle difference.

@Andrew0000
Copy link
Author

Andrew0000 commented Jan 25, 2023

@bentrengrove Thank you for your response and sorry for late reaction.

However I meant that this is a bit confusing:
The difference between remember(key) and derivedStateOf is in the amount of recomposition. derivedStateOf {} is used when your state or key is changing more than you want to update your UI.
As you can see by the example above we can use remember(key) and dependent composable will be updated only if the resulting value changes. This is really impressive ability of composables. And the expression inside remember(key) is calculated only if key changed.

I'm not quite sure I understand the statement With derivedStateOf it wouldn't even have to evaluate whether to skip it or not. It would be great if you can explain where exactly evaluation will be skipped?

In the following example //2 invokes as much as frequentlyChangedState changes:

val valueToDisplay2 = remember {
    Timber.i("test_ before derivedStateOf") // 1
    derivedStateOf {
        Timber.i("test_ inside derivedStateOf") // 2
        frequentlyChangedState.value / 2
    }
}

@Andrew0000
Copy link
Author

Well, looks like crucial distinction is that remember {} is Composable whereas derivedStateOf {} not and therefore a new State stream can be created even outside Composable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment