One Off the Slack: Why Do We Need SideEffect?
Florian Walther asked:
Even tho I read the documentation, I can’t wrap my head around why we need to use
SideEffect
here. The functionality works without theSideEffect
call. Can someone tell me why we need it? https://google.github.io/accompanist/systemuicontroller/
The code in question is from the current Accompanist documentation for its system UI controller support:
// Remember a SystemUiController
val systemUiController = rememberSystemUiController()
val useDarkIcons = MaterialTheme.colors.isLight
SideEffect {
// Update all of the system bar colors to be transparent, and use
// dark icons if we're in light theme
systemUiController.setSystemBarsColor(
color = Color.Transparent,
darkIcons = useDarkIcons
)
// setStatusBarsColor() and setNavigationBarsColor() also exist
}
Google’s Adam Powell attempted to explain:
Composition is a transaction. Anything you do in a
@Composable
function shouldn’t have observable side effects until after that transaction commits successfully.SideEffect {}
does this, deferring its block of code until the composition transaction that scheduled it is successful.
SideEffect
is also guaranteed to run that code on the applier thread (e.g. the Android UI thread) whereas composition itself may run on a background thread in the future
If composition fails, then nothing in that composition transaction is meant to have ever happened. By using
SideEffect
you can meet this contract. Otherwise you would need to ensure yourself that no mutations you make are visible externally before composition succeeds.
In this case, the system UI (e.g., status bar) is not even in our app, let alone in our
composition. Anything that we do to it from a composable is, by definition, a side effect
of that composable and should be handled via SideEffect
(or perhaps some other type of Effect
).
Florian seemed unconvinced:
So the difference is that without
SideEffect
the call tosetSytemBarsColor
would execute if the Composable was canceled for some reason?
but in reality it would probably not make any observable difference, is that correct?
Adam focused on correctness:
Writing wrong code that works by luck will generally come back to bite you eventually 🙂
Read the original thread in the kotlinlang Slack workspace. Not a member? Join that Slack workspace here!