HomeAndroidMove by Worth vs CompositionLocal vs Static CompositionLocal

Move by Worth vs CompositionLocal vs Static CompositionLocal


There are just a few methods you may move knowledge to a composable operate:

Move by Worth is a traditional method. CompositionLocal and static CompositionLocal is a Jetpack Compose method however static CompositionLocal is ineffective in my view (will likely be defined later).

Move by Worth

This can be a quite simple instance to move counter worth to the Mother or father() composable operate, then increments it by 1 and passes it to the Little one() composable operate. Lastly, it calls the GrandChild() composable operate with none parameters.

Let’s examine the code, what do you assume the Logcat outputs are in the course of the first composition and the next recomposition?

personal val tag = "CompLocal"

@Composable
enjoyable PassByValueDemo() {

    var counter by keep in mind {
        mutableStateOf(-1)
    }

    MyButton(onClick = { ++counter }, textual content = "PassByValue Demo")

    if(counter < 0) return

    Log.d(tag, "************** Move by Worth **************")
    Mother or father(counter)
}

@Composable
personal enjoyable Mother or father(worth: Int) {
    Log.d(tag, "Begin Mother or father - worth: $worth")
    Little one(worth + 1)
    Log.d(tag, "Finish Mother or father - worth: $worth")
}

@Composable
personal enjoyable Little one(worth: Int) {
    Log.d(tag, "Begin Little one - worth: $worth")
    GrandChild()
    Log.d(tag, "Finish Little one - worth: $worth")
}


@Composable
personal enjoyable GrandChild() {
    Log.d(tag, "Begin GrandChild")
    Log.d(tag, "Finish GrandChild")
}

Logcat Output – First Composition (first clicked)

worth is incremented by 1 and handed into the Little one() composable

************** Move by Worth **************
Begin Mother or father - worth: 0
Begin Little one - worth: 1
Begin GrandChild
Finish GrandChild
Finish Little one - worth: 1
Finish Mother or father - worth: 0

Logcat Output – Recomposition (second clicked)

An important factor to note is the GrandChild() composable is skipped.

************** Move by Worth **************
Begin Mother or father - worth: 1
Begin Little one - worth: 2
Finish Little one - worth: 2
Finish Mother or father - worth: 1

CompositionLocal

To perform the precise habits, CompositionLocal can be utilized.

Listed below are the easy steps:

  1. Create a CompositionLocal variable (utilizing compositionLocalOf() that’s accessible from the compostable capabilities that you simply wish to use it.

     personal val LocalInt = compositionLocalOf { 0 }
    
  2. Present worth to the CompositionLocal (i.e. LocalInt) utilizing CompositionLocalProvider.

     CompositionLocalProvider(
         LocalInt supplies 0,
     ) {
         
     }
    
  3. Entry the CompositionLocal ‘s worth by CompositionLocal.present.

     LocalInt.present
    

The total code appears to be like like this

personal val LocalInt = compositionLocalOf { 0 }
personal val tag = "CompLocal"

@Composable
enjoyable CompositionLocalDemo() {

    var counter by keep in mind {
        mutableStateOf(-1)
    }

    MyButton(onClick = { ++counter }, textual content = "CompositionLocal Demo")

    if(counter < 0) return

    Log.d(tag, "************** Utilizing CompositionLocal **************")
    CompositionLocalProvider(
        LocalInt supplies counter,
    ) {
        Mother or father()
    }
}

@Composable
personal enjoyable Mother or father() {
    Log.d(tag, "Begin Mother or father - LocalInt: ${LocalInt.present} ")

    CompositionLocalProvider(
        LocalInt supplies LocalInt.present + 1,
    ) {
        Little one()
    }

    Log.d(tag, "Finish Mother or father - LocalInt: ${LocalInt.present}")
}

@Composable
personal enjoyable Little one() {
    Log.d(tag, "Begin Little one - LocalInt: ${LocalInt.present} ")

    GrandChild()

    Log.d(tag, "Emd Little one - LocalInt: ${LocalInt.present} ")
}

@Composable
personal enjoyable GrandChild() {
    Log.d(tag, "Begin GrandChild")

    Log.d(tag, "Finish GrandChild")
}

This has the identical outputs because the Move by Worth instance above.

Logcat Output – First Composition (first clicked)

************** Move by Worth **************
Begin Mother or father - worth: 0
Begin Little one - worth: 1
Begin GrandChild
Finish GrandChild
Finish Little one - worth: 1
Finish Mother or father - worth: 0

Logcat Output – Recomposition (second clicked)

************** Move by Worth **************
Begin Mother or father - worth: 1
Begin Little one - worth: 2
Finish Little one - worth: 2
Finish Mother or father - worth: 1

Static CompositionLocal

You may change CompositionLocal with static CompositionLocal. This code

personal val LocalInt = compositionLocalOf { 0 }

is changed by

personal val LocalInt = staticCompositionLocalOf { 0 }

and every part stays the identical.

Nonetheless, the outputs are NOT the identical as Move by Worth and CompositionLocal. Adjustments to the CompositionLocal‘s worth triggers the whole composition tree to be recomposed.

Logcat Output – First Composition (first clicked)

************** Move by Worth **************
Begin Mother or father - worth: 0
Begin Little one - worth: 1
Begin GrandChild
Finish GrandChild
Finish Little one - worth: 1
Finish Mother or father - worth: 0

Logcat Output – Recomposition (second clicked)

************** Move by Worth **************
Begin Mother or father - worth: 1
Begin Little one - worth: 2
Begin GrandChild
Finish GrandChild
Finish Little one - worth: 2
Finish Mother or father - worth: 1

As you may see, GrandChild() composable operate is known as/recomposed despite the fact that it would not entry the LocalInt.present worth. This can be a full waste of pointless recompositions in my view.

The official doc states that it’s best to solely use staticCompositionLocalOf() for a worth that does not change. However the challenge is, how do you stop the person or any developer from altering it? You may’t.

Subsequently, it appears to be we should always simply use CompositionLocalOf() and NOT use staticCompositionLocalOf() as a finest follow.

The official doc does point out about efficiency advantages of utilizing staticCompositionLocalOf if the worth just isn’t modified, however how a lot advantages precisely?

I agree to make use of staticCompositionLocalOf() provided that it’s a fixed worth and cannot be modified. Then, this prevents the customers from misusing it. What do you assume?

Conclusion

CompositionLocal is only a Jetpack Compose method as a alternative of passing by worth to a composable operate. This can be useful if in case you have a worldwide variable that’s usually being utilized by your composable capabilities.

Static CompsitionLocal triggers the whole composable tree to be recomposed if its worth is modified. So, use it rigorously. My suggestion is do not use it.

Supply Code

GitHub Repository: Demo_UnderstandComposeConcept

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments