【问题标题】:Why can I get the correct result when I use the function writes to a local variable in Compose ?为什么我在 Compose 中使用函数写入局部变量时可以得到正确的结果?
【发布时间】:2021-10-06 09:26:49
【问题描述】:

代码 A 基于 article

有人告诉我,如果函数写入局部变量,这段代码将不是线程安全的或不正确的,我会得到错误的结果。

1:我用 Code A 测试它,但我总是得到正确的结果,为什么?

2:代码 B 是否正确?

代码 A

@Composable
fun ListWithBug(myList: List<String>) {
    var items = 0

    Row(horizontalArrangement = Arrangement.SpaceBetween) {
        Column {
            for (item in myList) {
                Text("Item: $item")
                items++ // Avoid! Side-effect of the column recomposing.
            }
        }
        Text("Count: $items")
    }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApp {
                ListWithBug(mutableListOf("a","b","c","d","e","f","g","h","k","j"))
            }
        }
    }
}

代码 B

@Composable
fun ListWithBug(myList: List<String>) {
    var items by remember { mutableStateOf(0) }

    Row(horizontalArrangement = Arrangement.SpaceBetween) {
        Column {
            for (item in myList) {
                Text("Item: $item")
                items++ // Avoid! Side-effect of the column recomposing.
            }
        }
        Text("Count: $items")
    }
}

【问题讨论】:

  • 请在您的帖子中添加 [kotlin](或其他使用的语言)标签,以便您的代码突出显示并更易于阅读

标签: android-studio kotlin android-jetpack-compose


【解决方案1】:

在实际情况下它不会按预期工作。它可能对您有用,因为您正在隔离测试它。每当 Composable 重构时,它都会重新初始化其中声明的所有变量。因此,如果某些东西 s=触发了 Composable 的重组,它会将items var 重新初始化为 0。我说它在实际应用中不起作用,因为在那个地方,有一个用户正在与之交互的可组合物池.按下按钮可能会导致多次重组,因此在本地可组合项中保持这种状态是不安全的。

第二种方法可能很好,但完全不推荐,因为它可能导致其他可组合项之间的状态不一致,因为理想情况下,您应该将所有 UI 状态存储在 viewmodel 中。它充当单一事实来源,所有可组合项都可以通过这种方式从一个地方读取状态。

您可以了解状态提升,以便与 Compose 一致地使用视图模型。只需查看this codelab

也许特别是this 页面,但总体上肯定会去codelab。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 2013-09-02
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    相关资源
    最近更新 更多