Orhan Tozan
02/26/2021, 11:10 AMremember(a, b) { a + b}
or derivedStateOf { a + b }
?lewis
02/26/2021, 11:37 AMderivedStateOf
should be used to calculate a new State
based on an existing State
, in your example remember
is the correct function.Orhan Tozan
02/26/2021, 11:42 AMremember
know which parameters it depends on, while derivedStateOf does it out-of-the-boxtext
could have been state, and derivedStateOf()
would a been used, with no need for specifying that it depends on text
Dominaezzz
02/26/2021, 11:45 AMlewis
02/26/2021, 11:48 AMderivedStateOf
is more powerful than I realised.Dominaezzz
02/26/2021, 11:48 AMOrhan Tozan
02/26/2021, 11:49 AMDominaezzz
02/26/2021, 11:50 AMval annotated text = remember { derivedStateOf { parseAnnotated(text) } }
how it should be used.Orhan Tozan
02/26/2021, 11:52 AMvar a by remember { mutableStateOf(0) }
var b by remember { mutableStateOf(0) }
val sum = derivedStateOf { a + b }
I assume remember doesn't have to be used here. We dont have to let derivedStateOf know that it depends on a and b, in contrast to remember {}Dominaezzz
02/26/2021, 11:55 AMOrhan Tozan
02/26/2021, 11:56 AMvar a by remember { mutableStateOf(0) }
var b by remember { mutableStateOf(0) }
val sum = derivedStateOf { expensiveAlgorithmComputation(a, b) }
How about now?Dominaezzz
02/26/2021, 11:57 AMvar a by remember { mutableStateOf(0) }
var b by remember { mutableStateOf(0) }
val sum = remember { derivedStateOf { expensiveAlgorithmComputation(a, b) } }
This is how it should be written.Orhan Tozan
02/26/2021, 11:58 AMvar text by remember { mutableStateOf("") }
val annotatedText = derivedStateOf { parseAnnotated(text) }
remember
here? The derivedStateOf docs says that it performs caching:
Creates a State object whose State.value is the result of calculation. The result of calculation will be cached in such a way that calling State.value repeatedly will not cause calculation to be executed multiple times, but reading State.value will cause all State objects that got read during the calculation to be read in the current Snapshot, meaning that this will correctly subscribe to the derived state objects if the value is being read in an observed context such as a Composable function.Source: https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#derivedstateof
@Composable fun Example() {
var a by mutableStateOf(0)
var b by mutableStateOf(0)
val sum = derivedStateOf { a + b }
// Changing either a or b will cause CountDisplay to recompose but not trigger Example
// to recompose.
CountDisplay(sum)
}
Dominaezzz
02/26/2021, 12:01 PMOrhan Tozan
02/26/2021, 12:03 PMvar a by remember { mutableStateOf(0) }
var b by remember { mutableStateOf(0) }
`val sum = remember { derivedStateOf { expensiveAlgorithmComputation(a, b) } }````
Your example looks reaaally complex compared to ReactJS simple usage of useMemo()Dominaezzz
02/26/2021, 12:03 PMOrhan Tozan
02/26/2021, 12:08 PMvar a by remember { mutableStateOf(0) }
var b by remember { mutableStateOf(0) }
`val sum = remember { derivedStateOf { expensiveAlgorithmComputation(a, b) } }````
Whats the point here actually of derivedStateOf? Is this not the same effect?:
var a by remember { mutableStateOf(0) }
var b by remember { mutableStateOf(0) }
`val sum = remember(a, b) { expensiveAlgorithmComputation(a, b) }````Dominaezzz
02/26/2021, 12:12 PMOrhan Tozan
02/26/2021, 12:14 PMDominaezzz
02/26/2021, 12:14 PMOrhan Tozan
02/26/2021, 12:17 PMDominaezzz
02/26/2021, 12:19 PMOrhan Tozan
02/26/2021, 12:19 PMrememberWithMagic {}
Dominaezzz
02/26/2021, 12:23 PMOrhan Tozan
02/26/2021, 12:23 PMDominaezzz
02/26/2021, 12:25 PMOrhan Tozan
02/26/2021, 12:26 PMZach Klippenstein (he/him) [MOD]
02/26/2021, 3:36 PMderivedStateOf
“automatically” knows its dependencies, but remember
does not, is because of how snapshots work in compose. I recently tried to kind of explain how the snapshotting semantics work, and how it applies here is that derivedStateOf
is a snapshot reader – after the first execution of that lambda, it will be notified any time a snapshot is applied that modifies any of the state objects in that lambda. This is super convenient, but comes at a price – it needs to do a lot more bookkeeping to track changes. It also returns a State
instead of the raw value, which means:
1. The calling recompose scope doesn’t need to recompose if one of the dependencies change, only the scopes that are actually reading the state value do (e.g. if you call derivedStateOf in a composable but then only read the actual state value inside of composable lambdas passed to children).
2. The returned State
object actually checks for modifications when the value is read. This is why it doesn’t need any explicit disposal.
remember
is much simpler and doesn’t do any bookkeeping, which makes it much cheaper to use. It returns the raw value returned from the lambda, which means that if it wants to return a new value (e.g. when one of its dependencies is changed), the entire calling recompose scope needs to be recomposed. It tracks dependencies not by using the snapshot mechanism, but instead by simply comparing the key values on each call.Sean McQuillan [G]
02/26/2021, 7:14 PMderivedStateOf
because the API doesn't exist when that presentation was made (it very well could if it was being written today - which would probably cause a different example to be chosen as that section was about introducing remember 🙂 ).