Home > Blockchain >  Value is remembered without using remember
Value is remembered without using remember

Time:05-21

Eventough I haven't used remember keyword values are still remembered between recomposition. While tutorials say that it shouldn't. I am trying to understand all this mess around Compose State Variables but things work differently then explained.

enter image description here

package com.example.testcompose

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue

class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {

      var state by mutableStateOf(1)
      Button({state  = 1 }) { Text("$state") }

    }
  }
}

CodePudding user response:

Here is extended code which demonstrated that Button and Text behave differently. In both cases I am NOT using remember. But Button is behaving as if I am using rmemeber.

//==================================================================
// MAIN ACTIVITY
//==================================================================
class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      Column {
        MyButton()  //Behaves incorrectly like there is remember 
        MyText()    //Behaves correctly not remembering the value 
      }
    }
  }
}

@Composable
fun MyButton(){
  Column {
    var state by mutableStateOf("Hello ")
    Button({ state  = "you " }) { Text(state) }
  }
}

@Composable
fun MyText(){
  Column {
    var state by mutableStateOf("Hello ") 
    Text(state, modifier = Modifier.clickable(onClick = { state  = "you " } ) )
  }
}

CodePudding user response:

As mentioned by Google:

Recomposition is the process of calling your composable functions again when inputs change. This happens when the function's inputs change. When Compose recomposes based on new inputs, it only calls the functions or lambdas that might have changed, and skips the rest. By skipping all functions or lambdas that don't have changed parameters, Compose can recompose efficiently.

Let's change your code to this:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Column {
                MyComposable()
            }
        }
    }
}

@Composable
fun MyComposable() {
    Column {
        var state1 by mutableStateOf("Hello ")
        Button({ state1  = "you " }) { Text(state1) }
        var state2 by mutableStateOf("Hello ")
        Text(state2, modifier = Modifier.clickable(onClick = { state2  = "you " }))
    }
}

You will see that even though button behaves correctly, text changes both values due to recomposition. So as mentioned by Google because of the underline mechanism of Compose it is unpredictable how the code runs or might skip part of the execution of the code. So you should always use remember on this situations in order to have the expected outcome.

Please read carefully Thinking in Compose.

  • Related