rememberUpdatedState 学习

54 阅读1分钟
    @Composable
    fun showText(
        num:Int,
    ) {
        var showText by remember {
            mutableStateOf("")
        }
        LaunchedEffect (key1 = Unit){
            delay(3000)
            showText = "$num"
        }
        Text(text = showText)
    }

这里期望的是 3s之后 showText 重新赋值最新的num。但是会发现num不管怎么改变,执行shouText = "$num"的时候的num 永远是第一次传入的num。

只是点 1 LaunchedEffect 在key 不变的情况下只会执行一次。 2 参数block,中如果饮用固定的变量。即使变量后边修改了,也不会影响block里面引用该变量的值。(个人理解)

解决办法 1 动态修改key。

   @Composable
   fun showText(
       num:Int,
   ) {
       var showText by remember {
           mutableStateOf("")
       }
       LaunchedEffect (key1 = num){
           delay(3000)
           showText = "$num"
       }
       Text(text = showText)
   }

当key设置成num,num只要修改 就会重启LaunchedEffect,showText也能拿到最新的num。但是delay也会重新执行。也就是每次数字修改都得等3s,才能刷新。

解决办法 2 使用 rememberUpdatedState

  @Composable
    fun showText(
        num:Int,
    ) {
        val showNum by rememberUpdatedState(newValue = num)
        var showText by remember {
            mutableStateOf("")
        }
        LaunchedEffect (key1 = Unit){
            delay(3000)
            showText = "$showNum"
        }
        Text(text = "showText==$showText",)
    }

这种写法的本质是:

rememberUpdatedState的源码如下

@Composable
fun <T> rememberUpdatedState(newValue: T): State<T> = remember {
    mutableStateOf(newValue)
}.apply { value = newValue }

所以上面 rememberUpdatedState 的解决办法可以写成这样

   @Composable
    fun showText(
        num:Int,
    ) {
        var showNum by remember {
            mutableIntStateOf(num)
        }
        showNum  = num
        var showText by remember {
            mutableStateOf("")
        }
        LaunchedEffect (key1 = Unit){
            delay(3000)
            showText = "$showNum"
        }
        Text(text = "showText==$showText",)
    }

执行之所以拿不到 是因为 3s之后给showText赋值的是一个固定的值。新的代码之所以能拿到是因为给showNum赋值的是一个 mutableIntStateOf()。