将状态值或状态作为可组合函数参数传递

Jay*_*aig 21 android android-jetpack-compose

在可组合函数中,我可以将 State 或 State 的值作为参数传递。有什么理由更愿意传递 State 的价值而不是 State 的价值?

在这两种情况下,可组合项都是无状态的,那么为什么要区分这两种情况呢?

Sve*_*obs 11

State通过或仅有关重组的值之间存在细微差别State

让我们从传递开始State

@Composable
fun Example1(text: State<String>) {
  SideEffect { Log.d("Example", "Example1 recomposition") }
  Example2(text)
}

@Composable
fun Example2(text: State<String>) {
  SideEffect { Log.d("Example", "Example2 recomposition") }
  Text(text.value)
}

@Composable
fun Screen() {
  val text = remember { mutableStateOf("hello") } }

  Example1(text)

  Button(
    onClick = { text.value = "world" }
  ) {
    Text("Click me")
  }
}

Run Code Online (Sandbox Code Playgroud)

第一次启动时,您将看到日志输出

Example1 recomposition
Example2 recomposition
Run Code Online (Sandbox Code Playgroud)

但是,当您单击该按钮时,您只会看到附加的

Example2 recomposition
Run Code Online (Sandbox Code Playgroud)

因为你传递下来的State只是Example2读取状态,Example1不需要重构。

让我们将参数更改为普通类型:

Example1 recomposition
Example2 recomposition
Run Code Online (Sandbox Code Playgroud)

现在单击该按钮时,您将在日志输出中看到另外两行

Example1 recomposition
Example2 recomposition
Run Code Online (Sandbox Code Playgroud)

由于text现在是两个可组合项的函数签名的普通类型,因此当值更改时都需要重新组合。

然而,总是传递State会变得相当麻烦。Compose 非常擅长检测需要重构的内容,因此这应该被视为微观优化。我只是想指出,每个使用 Compose 的开发人员都应该了解一点细微的差别。


Bré*_*ira 2

可以传递状态的值。例如:

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

        val isLoading = mutableStateOf(false)
        val onClickAtButton = {
            lifecycleScope.launch(Dispatchers.Main) {
                isLoading.value = true
                withContext(Dispatchers.IO) {
                    //Do some heavy operation live REST call
                }
                isLoading.value = false
            }
        }

        setContent {
            MyComposable(isLoading.value, onClickAtButton)
        }
    }
}


@Composable
fun MyComposable(
    isLoading: Boolean = false,
    onClickAtButton: () -> Unit = {}
){

    Box(modifier = Modifier.fillMaxSize(){
    
        Button(onClick = onClickAtButton)

        if(isLoading){
            CircularProgressIndicator()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

希望它对某人有帮助。