user1307179
user1307179

Reputation: 283

Android Compose SideEffect

What's difference between these 2? one using SideEffect, the other doesn't. "SideEffect is invoked on every successful recomposition", but without SideEffect, it is also run on every recomposition.

@Composable
fun BackHandler(
    backDispatcher: OnBackPressedDispatcher,
    enabled: Boolean = true, // Whether back events should be intercepted or not
    onBack: () -> Unit
) {
    val backCallback = remember { /* ... */ }

    // On every successful composition, update the callback with the `enabled` value
    // to tell `backCallback` whether back events should be intercepted or not
    SideEffect {
        backCallback.isEnabled = enabled
    }

    /* Rest of the code */
}

@Composable
fun BackHandler(
    backDispatcher: OnBackPressedDispatcher,
    enabled: Boolean = true, // Whether back events should be intercepted or not
    onBack: () -> Unit
) {
    val backCallback = remember { /* ... */ }

    backCallback.isEnabled = enabled

    /* Rest of the code */
}

Upvotes: 5

Views: 965

Answers (1)

chuckj
chuckj

Reputation: 29635

The difference is in the term "successful". The effects of a call to BackHandler are not guaranteed to be part of the resulting composition even if it is called (there ways it can be discarded are rare and difficult to describe). SideEffect ensures the lambda is only executed if they are.

A SideEffect ensures that,

  1. It is only applied when the effect of the enclosing scope is actually part of the resulting composition.
  2. It is called after the composition has been realized into the resulting composition (that is the LayoutNodes have been created and successfully inserted into to the layout tree). This is important internally (for things such as focus) but might not have that much application outside the framework internals.
  3. It is a separate snapshot than was was taken for composition and any observable changes will affect the next composition, not this one.
  4. It is always called on the applier's thread (that is the Main thread for LayoutNodes).

Only (1) above is relevant here.

It is considered bad practice for a composable function to have a side-effect not encapsulated by SideEffect or similar construct as doing so breaks the assumption that composable function are referentially transparent with respect to the composition.

Upvotes: 6

Related Questions