gitai
06/20/2021, 11:01 AMremember()
over rememberSaveable()
? and … is it really required to explicitly call remember()
in such use-case?
For example, here (see code in reply) the compiler will presumably add code to the Button
composable content lambda to implicitly "remember" the captured MutableState<Boolean>
instance referenced by hidden
and restore it when the Button
is clicked - that is when executing the content lambda again during recomposition. Since this lambda in the only composable to run upon such event I don't see why you would explicitly remember hidden
at it’s declaration point, which kind of leads to a more basic question: Should we use remember()
/ rememberSaveable()
"defensibly" to guard against recompositions at higher levels which may happen "out of the blue" ?gitai
06/20/2021, 11:01 AMclass MainActivity : ComponentActivity() { @SuppressLint("UnrememberedMutableState")
@Composable
fun Widget() {
var hidden by mutableStateOf(true)
Column() {
Button(onClick = { hidden = !hidden }) {
Text(text = if (hidden) "Show" else "Hide")
}
}
} override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
Widget()
}
}
}
}
Albert Chang
06/20/2021, 1:58 PMgitai
06/20/2021, 3:06 PMAlbert Chang
06/20/2021, 4:00 PMWhen and how often recomposition happens shouldn't affect correctness of your program.
This is the principle. Restarting animation from where it stopped is not always the correctness, but keeping the
hidden
state obviously is.Albert Chang
06/20/2021, 4:01 PMrememberSaveable
vs remember
, not remember
vs not remembering.gitai
06/20/2021, 4:53 PMWhen and how often recomposition happens shouldn't affect correctness of your program.
This is the principle. Restarting animation from where it stopped is not always the correctness, but keeping the hidden state obviously is.Well, I'm not exactly sure recomposition is or should be expected universal throughout the app...
As for savesbles, it's the problem of rememberSaveable vs remember, not remember vs not remembering.It actually is, if you can't / don't use rememberSaveable() to store the state, for whatever reason, like type serialization difficulties then why call remember() at all - why make any explicit effort to "remember" anything
gitai
06/20/2021, 5:05 PMtad
06/20/2021, 8:49 PMremember
is an optimization. If your state is complex to calculate on every recomposition (e.g. every frame) then remember
allows you to memoize that state. Ideally, though, you'd hoist as much as possible (or as much as makes sense from an API standpoint) to avoid calculating that state in the first place.tad
06/20/2021, 8:53 PMremember
as a crutch to force idempotency, and that led to several subtle bugs and unnecessary recompositions. So it's tricky to get right for sure.gitai
06/20/2021, 9:56 PMremember()
in cases where your initial read is in the same scope where the state is created so you can have the scope itself register for recomposition in order to pass state updates to some transient widget which can only accept state through function arguments.Albert Chang
06/21/2021, 12:15 AMgitai
06/21/2021, 5:59 AMgitai
06/21/2021, 7:11 AMAlbert Chang
06/21/2021, 7:14 AMgitai
06/21/2021, 7:26 AMAlbert Chang
06/21/2021, 7:30 AMhidden
state, no matter how many times the function is called, the button will always have the remembered value. If you don't remember it, when hidden
is false and the function is called again, it'll be reset to true.gitai
06/21/2021, 7:46 AMIf you remember hidden state, no matter how many times the function is called, the button will always have the remembered valueOnly if the Button was not clicked between calls to Widget. If Widget may be recomposed at any point in time, then you have no definitive answer as to its result – it can display [ Show ] or [Hide] – you don’t know.
If you don't remember it, when hidden is false and the function is called again, it'll be reset to true.Which is exactly what makes calls to Widget idempotent - it always displays the same button: [ Show ] regardless of any side effect.
Albert Chang
06/21/2021, 7:54 AMIdempotence is the property of certain operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application.You can learn more about idempotence if you do some searching yourself. If you don't remember
hidden
, every call to the function will reset it to initial state, which itself is a side effect.gitai
06/21/2021, 7:59 AMif you don't remember hidden, every call to the function will reset it to initial state, which itself is a side effect.I disagree. if I don't remember
hidden
I'm invoking a new instance of the function (Widget) - I'm not resetting anything.Albert Chang
06/21/2021, 8:02 AMgitai
06/21/2021, 8:10 AMAlbert Chang
06/21/2021, 8:11 AMgitai
06/21/2021, 8:31 AMAlbert Chang
06/21/2021, 8:46 AMgitai
06/21/2021, 9:55 AMAlbert Chang
06/21/2021, 9:55 AMgitai
06/21/2021, 10:05 AMgitai
06/21/2021, 11:20 AMAlbert Chang
06/21/2021, 11:30 AMgitai
06/21/2021, 11:40 AMAlbert Chang
06/21/2021, 12:12 PM