Home > other >  Use of LaunchedEffect vs SideEffect in jetpack compose
Use of LaunchedEffect vs SideEffect in jetpack compose

Time:09-22

Hi guys I am learning side-effect in my project. I want to know when should I use LaunchedEffect and SideEffect in which scenario. I am adding some piece of code using both effect. Please lemme know if I am doing wrong here.

1st using LaunchedEffect, please guide me if we need effect on this function or not.

@Composable
fun BluetoothRequestContinue(multiplePermissionsState: MultiplePermissionsState) {
    var launchPermission by remember { mutableStateOf(false) }
    if (launchPermission) {
        LaunchedEffect(Unit) {
            multiplePermissionsState.launchMultiplePermissionRequest()
        }
    }
    AbcMaterialButton(
        text = stringResource(R.string.continue_text),
        spacerHeight = 10.dp
    ) {
        launchPermission = true
    }
}

2nd using SideEffect to open setting using intent

@Composable
fun OpenPermissionSetting(router: Router = get()) {
    val activity = LocalContext.current as Activity
    var launchSetting by remember { mutableStateOf(false) }
    if (launchSetting) {
        SideEffect {
            activity.startActivity(router.permission.getPermissionSettingsIntent(activity))
        }
    }
    AbcMaterialButton(
        text = stringResource(R.string.open_settings),
        spacerHeight = 10.dp
    ) {
        launchSetting = true

    }
}

Please let me know if we need Effect or not. Also guide me if we need different effect as well. Thanks

CodePudding user response:

There difference between

   if (launchSetting) {
        SideEffect {
            // Do something
        }
    }

and

   if (launchPermission) {
        LaunchedEffect(Unit) {
            multiplePermissionsState.launchMultiplePermissionRequest()
        }
    }

both enters recomposition when conditions are true but LaunchedEffect is only invoked once because its key is Unit. SideEffect is invoked on each recomposition as long as condition is true.

SideEffect function can be used for operations that should be invoked only when a successful recomposition happens

Recomposition starts whenever Compose thinks that the parameters of a composable might have changed. Recomposition is optimistic, which means Compose expects to finish recomposition before the parameters change again. If a parameter does change before recomposition finishes, Compose might cancel the recomposition and restart it with the new parameter.

When recomposition is canceled, Compose discards the UI tree from the recomposition. If you have any side-effects that depend on the UI being displayed, the side-effect will be applied even if composition is canceled. This can lead to inconsistent app state.

Ensure that all composable functions and lambdas are idempotent and side-effect free to handle optimistic recomposition.

Sample from official docs

To share Compose state with objects not managed by compose, use the SideEffect composable, as it's invoked on every successful recomposition.

@Composable
fun rememberAnalytics(user: User): FirebaseAnalytics {
    val analytics: FirebaseAnalytics = remember {
        /* ... */
    }

    // On every successful composition, update FirebaseAnalytics with
    // the userType from the current User, ensuring that future analytics
    // events have this metadata attached
    SideEffect {
        analytics.setUserProperty("userType", user.userType)
    }
    return analytics
}

LaunchedEffect is for calling a function on composition or on recomposition if keys are changed.

If you write your LaunchedEffect as

LaunchedEffect(key1= launchPermission) {
   if(launchPermission) {
     // Do something
  }
}

code block inside if will not be called in composition if key is not true but whenever it changes from false to true code block will be invoked. This is useful for one-shot operations that are not fired by user interaction directly or when an operation requires a CoroutineScope invoked after user interaction, animations or calling suspend functions such as lazyListState.animateScrollToItem()

Definition of concept of side-effect from Wikipedia

In computer science, an operation, function or expression is said to have a side effect if it modifies some state variable value(s) outside its local environment, which is to say if it has any observable effect other than its primary effect of returning a value to the invoker of the operation. Example side effects include modifying a non-local variable, modifying a static local variable, modifying a mutable argument passed by reference, performing I/O or calling other functions with side-effects. In the presence of side effects, a program's behaviour may depend on history; that is, the order of evaluation matters. Understanding and debugging a function with side effects requires knowledge about the context and its possible histories.

  • Related